From a3fbe72717ee213e0cabf36cebbefd3a8130a82e Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Thu, 22 Dec 2022 16:34:29 +0100 Subject: [PATCH 01/36] docs: audit, deploymentconfig, files, parameters --- coderd/apidoc/docs.go | 1491 ++++++++-- coderd/apidoc/swagger.json | 1119 ++++++- coderd/audit.go | 19 + coderd/deploymentconfig.go | 7 + coderd/files.go | 18 + coderd/parameters.go | 30 + coderd/templates.go | 2 +- codersdk/audit.go | 4 +- codersdk/parameters.go | 16 +- codersdk/workspacebuilds.go | 2 +- docs/api/audit.md | 129 + docs/api/files.md | 77 + docs/api/general.md | 863 +++++- docs/api/parameters.md | 208 ++ docs/api/schemas.md | 2579 ++++++++++++++++- docs/api/templates.md | 68 +- docs/api/workspaces.md | 20 +- docs/manifest.json | 12 + .../markdown-template/code_shell.dot | 6 +- scripts/apidocgen/markdown-template/main.dot | 3 - .../apidocgen/markdown-template/operation.dot | 2 - 21 files changed, 6334 insertions(+), 341 deletions(-) create mode 100644 docs/api/audit.md create mode 100644 docs/api/files.md create mode 100644 docs/api/parameters.md diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index e674cf6222bdd..5ff12f9fb8f8f 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -97,6 +97,92 @@ const docTemplate = `{ } } }, + "/audit": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Audit" + ], + "summary": "Get audit logs", + "operationId": "get-audit-logs", + "parameters": [ + { + "type": "string", + "description": "Search query", + "name": "q", + "in": "query", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "After ID", + "name": "after_id", + "in": "query" + }, + { + "type": "integer", + "description": "Page limit", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "description": "Page offset", + "name": "offset", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.AuditLogResponse" + } + } + } + } + }, + "/audit/testgenerate": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "tags": [ + "Audit" + ], + "summary": "Generate fake audit log", + "operationId": "generate-fake-audit-logs", + "parameters": [ + { + "description": "Audit log request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateTestAuditLogRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, "/authcheck": { "post": { "security": [ @@ -156,6 +242,31 @@ const docTemplate = `{ } } }, + "/config/deployment": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "General" + ], + "summary": "Get deployment config", + "operationId": "get-deployment-config", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.DeploymentConfig" + } + } + } + } + }, "/csp/reports": { "post": { "security": [ @@ -192,6 +303,81 @@ const docTemplate = `{ } } }, + "/files": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "description": "Notice: Swagger 2.0 doesn't support file upload with a ` + "`" + `content-type` + "`" + ` different than ` + "`" + `application/x-www-form-urlencoded` + "`" + `.", + "consumes": [ + "application/x-tar" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Files" + ], + "summary": "Upload file", + "operationId": "update-file", + "parameters": [ + { + "type": "string", + "default": "application/x-tar", + "description": "Content-Type must be ` + "`" + `application/x-tar` + "`" + `", + "name": "Content-Type", + "in": "header", + "required": true + }, + { + "type": "file", + "description": "File to be uploaded", + "name": "file", + "in": "formData", + "required": true + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.UploadResponse" + } + } + } + } + }, + "/files/{fileID}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": [ + "Files" + ], + "summary": "Get file by ID", + "operationId": "get-file-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "File ID", + "name": "fileID", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, "/organizations/{organization-id}/templates/": { "post": { "security": [ @@ -360,7 +546,7 @@ const docTemplate = `{ } } }, - "/templates/{id}": { + "/parameters/{scope}/{id}": { "get": { "security": [ { @@ -371,15 +557,27 @@ const docTemplate = `{ "application/json" ], "tags": [ - "Templates" + "Parameters" ], - "summary": "Update template metadata by ID", - "operationId": "update-template-metadata", + "summary": "Get parameters", + "operationId": "get-parameters", "parameters": [ + { + "enum": [ + "template", + "workspace", + "import_job" + ], + "type": "string", + "description": "Scope", + "name": "scope", + "in": "path", + "required": true + }, { "type": "string", "format": "uuid", - "description": "Template ID", + "description": "ID", "name": "id", "in": "path", "required": true @@ -389,66 +587,127 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/codersdk.Template" + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Parameter" + } } } } }, - "delete": { + "post": { "security": [ { "CoderSessionToken": [] } ], + "consumes": [ + "application/json" + ], "produces": [ "application/json" ], "tags": [ - "Templates" + "Parameters" ], - "summary": "Delete template by ID", - "operationId": "delete-template-by-id", + "summary": "Create parameter", + "operationId": "create-parameter", "parameters": [ + { + "description": "Parameter request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateParameterRequest" + } + }, + { + "enum": [ + "template", + "workspace", + "import_job" + ], + "type": "string", + "description": "Scope", + "name": "scope", + "in": "path", + "required": true + }, { "type": "string", "format": "uuid", - "description": "Template ID", + "description": "ID", "name": "id", "in": "path", "required": true } ], "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", "schema": { - "$ref": "#/definitions/codersdk.Response" + "$ref": "#/definitions/codersdk.Parameter" } } } } }, - "/updatecheck": { - "get": { + "/parameters/{scope}/{id}/{name}": { + "delete": { + "security": [ + { + "CoderSessionToken": [] + } + ], "produces": [ "application/json" ], "tags": [ - "General" + "Parameters" + ], + "summary": "Delete parameter", + "operationId": "delete-parameter", + "parameters": [ + { + "enum": [ + "template", + "workspace", + "import_job" + ], + "type": "string", + "description": "Scope", + "name": "scope", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Name", + "name": "name", + "in": "path", + "required": true + } ], - "summary": "Update check", - "operationId": "update-check", "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/codersdk.UpdateCheckResponse" + "$ref": "#/definitions/codersdk.Response" } } } } }, - "/users/{user}/workspace/{workspacename}": { + "/templates/{id}": { "get": { "security": [ { @@ -459,44 +718,30 @@ const docTemplate = `{ "application/json" ], "tags": [ - "Workspaces" + "Templates" ], - "summary": "Get workspace metadata by owner and workspace name", - "operationId": "get-workspace-metadata-by-owner-and-workspace-name", + "summary": "Get template metadata by ID", + "operationId": "get-template-metadata-by-id", "parameters": [ { "type": "string", - "description": "Owner username", - "name": "user", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Workspace name", - "name": "workspacename", + "format": "uuid", + "description": "Template ID", + "name": "id", "in": "path", "required": true - }, - { - "type": "boolean", - "description": "Return data instead of HTTP 404 if the workspace is deleted", - "name": "include_deleted", - "in": "query" } ], "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/codersdk.Workspace" + "$ref": "#/definitions/codersdk.Template" } } } - } - }, - "/workspaces": { - "get": { + }, + "delete": { "security": [ { "CoderSessionToken": [] @@ -506,17 +751,152 @@ const docTemplate = `{ "application/json" ], "tags": [ - "Workspaces" + "Templates" ], - "summary": "List workspaces", - "operationId": "get-workspaces", + "summary": "Delete template by ID", + "operationId": "delete-template-by-id", "parameters": [ { "type": "string", - "description": "Filter by owner username", - "name": "owner", - "in": "query" - }, + "format": "uuid", + "description": "Template ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + }, + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Update template metadata by ID", + "operationId": "update-template-metadata", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Template" + } + } + } + } + }, + "/updatecheck": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "General" + ], + "summary": "Update check", + "operationId": "update-check", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.UpdateCheckResponse" + } + } + } + } + }, + "/users/{user}/workspace/{workspacename}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Workspaces" + ], + "summary": "Get workspace metadata by owner and workspace name", + "operationId": "get-workspace-metadata-by-owner-and-workspace-name", + "parameters": [ + { + "type": "string", + "description": "Owner username", + "name": "user", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Workspace name", + "name": "workspacename", + "in": "path", + "required": true + }, + { + "type": "boolean", + "description": "Return data instead of HTTP 404 if the workspace is deleted", + "name": "include_deleted", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Workspace" + } + } + } + } + }, + "/workspaces": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Workspaces" + ], + "summary": "List workspaces", + "operationId": "get-workspaces", + "parameters": [ + { + "type": "string", + "description": "Filter by owner username", + "name": "owner", + "in": "query" + }, { "type": "string", "description": "Filter by template name", @@ -835,6 +1215,99 @@ const docTemplate = `{ } } }, + "codersdk.AuditDiff": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/codersdk.AuditDiffField" + } + }, + "codersdk.AuditDiffField": { + "type": "object", + "properties": { + "new": {}, + "old": {}, + "secret": { + "type": "boolean" + } + } + }, + "codersdk.AuditLog": { + "type": "object", + "properties": { + "action": { + "type": "string" + }, + "additional_fields": { + "type": "array", + "items": { + "type": "integer" + } + }, + "description": { + "type": "string" + }, + "diff": { + "$ref": "#/definitions/codersdk.AuditDiff" + }, + "id": { + "type": "string" + }, + "ip": { + "$ref": "#/definitions/netip.Addr" + }, + "is_deleted": { + "type": "boolean" + }, + "organization_id": { + "type": "string" + }, + "request_id": { + "type": "string" + }, + "resource_icon": { + "type": "string" + }, + "resource_id": { + "type": "string" + }, + "resource_link": { + "type": "string" + }, + "resource_target": { + "description": "ResourceTarget is the name of the resource.", + "type": "string" + }, + "resource_type": { + "type": "string" + }, + "status_code": { + "type": "integer" + }, + "time": { + "type": "string" + }, + "user": { + "$ref": "#/definitions/codersdk.User" + }, + "user_agent": { + "type": "string" + } + } + }, + "codersdk.AuditLogResponse": { + "type": "object", + "properties": { + "audit_logs": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.AuditLog" + } + }, + "count": { + "type": "integer" + } + } + }, "codersdk.AuthorizationCheck": { "description": "AuthorizationCheck is used to check if the currently authenticated user (or the specified user) can do a given action to a given set of objects.", "type": "object", @@ -854,183 +1327,739 @@ const docTemplate = `{ } } }, - "codersdk.AuthorizationObject": { - "description": "AuthorizationObject can represent a \"set\" of objects, such as: all workspaces in an organization, all workspaces owned by me, all workspaces across the entire product.", + "codersdk.AuthorizationObject": { + "description": "AuthorizationObject can represent a \"set\" of objects, such as: all workspaces in an organization, all workspaces owned by me, all workspaces across the entire product.", + "type": "object", + "properties": { + "organization_id": { + "description": "OrganizationID (optional) adds the set constraint to all resources owned by a given organization.", + "type": "string" + }, + "owner_id": { + "description": "OwnerID (optional) adds the set constraint to all resources owned by a given user.", + "type": "string" + }, + "resource_id": { + "description": "ResourceID (optional) reduces the set to a singular resource. This assigns\na resource ID to the resource type, eg: a single workspace.\nThe rbac library will not fetch the resource from the database, so if you\nare using this option, you should also set the owner ID and organization ID\nif possible. Be as specific as possible using all the fields relevant.", + "type": "string" + }, + "resource_type": { + "description": "ResourceType is the name of the resource.\n` + "`" + `./coderd/rbac/object.go` + "`" + ` has the list of valid resource types.", + "type": "string" + } + } + }, + "codersdk.AuthorizationRequest": { + "type": "object", + "properties": { + "checks": { + "description": "Checks is a map keyed with an arbitrary string to a permission check.\nThe key can be any string that is helpful to the caller, and allows\nmultiple permission checks to be run in a single request.\nThe key ensures that each permission check has the same key in the\nresponse.", + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/codersdk.AuthorizationCheck" + } + } + } + }, + "codersdk.AuthorizationResponse": { + "type": "object", + "additionalProperties": { + "type": "boolean" + } + }, + "codersdk.BuildInfoResponse": { + "type": "object", + "properties": { + "external_url": { + "description": "ExternalURL references the current Coder version.\nFor production builds, this will link directly to a release. For development builds, this will link to a commit.", + "type": "string" + }, + "version": { + "description": "Version returns the semantic version of the build.", + "type": "string" + } + } + }, + "codersdk.CreateParameterRequest": { + "description": "CreateParameterRequest is a structure used to create a new parameter value for a scope.", + "type": "object", + "required": [ + "destination_scheme", + "name", + "source_scheme", + "source_value" + ], + "properties": { + "copy_from_parameter": { + "description": "CloneID allows copying the value of another parameter.\nThe other param must be related to the same template_id for this to\nsucceed.\nNo other fields are required if using this, as all fields will be copied\nfrom the other parameter.", + "type": "string" + }, + "destination_scheme": { + "type": "string", + "enum": [ + "none", + "environment_variable", + "provisioner_variable" + ] + }, + "name": { + "type": "string" + }, + "source_scheme": { + "type": "string", + "enum": [ + "none", + "data" + ] + }, + "source_value": { + "type": "string" + } + } + }, + "codersdk.CreateTemplateRequest": { + "type": "object", + "required": [ + "name", + "template_version_id" + ], + "properties": { + "allow_user_cancel_workspace_jobs": { + "description": "Allow users to cancel in-progress workspace jobs.\n*bool as the default value is \"true\".", + "type": "boolean" + }, + "default_ttl_ms": { + "description": "DefaultTTLMillis allows optionally specifying the default TTL\nfor all workspaces created from this template.", + "type": "integer" + }, + "description": { + "description": "Description is a description of what the template contains. It must be\nless than 128 bytes.", + "type": "string" + }, + "display_name": { + "description": "DisplayName is the displayed name of the template.", + "type": "string" + }, + "icon": { + "description": "Icon is a relative path or external URL that specifies\nan icon to be displayed in the dashboard.", + "type": "string" + }, + "name": { + "description": "Name is the name of the template.", + "type": "string" + }, + "parameter_values": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.CreateParameterRequest" + } + }, + "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" + } + } + }, + "codersdk.CreateTestAuditLogRequest": { + "type": "object", + "properties": { + "action": { + "type": "string", + "enum": [ + "create", + "write", + "delete", + "start", + "stop" + ] + }, + "resource_id": { + "type": "string" + }, + "resource_type": { + "type": "string", + "enum": [ + "organization", + "template", + "template_version", + "user", + "workspace", + "workspace_build", + "git_ssh_key", + "api_key", + "group" + ] + }, + "time": { + "type": "string" + } + } + }, + "codersdk.DERP": { + "type": "object", + "properties": { + "config": { + "$ref": "#/definitions/codersdk.DERPConfig" + }, + "server": { + "$ref": "#/definitions/codersdk.DERPServerConfig" + } + } + }, + "codersdk.DERPConfig": { + "type": "object", + "properties": { + "path": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "url": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + } + } + }, + "codersdk.DERPRegion": { + "type": "object", + "properties": { + "latency_ms": { + "type": "number" + }, + "preferred": { + "type": "boolean" + } + } + }, + "codersdk.DERPServerConfig": { + "type": "object", + "properties": { + "enable": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" + }, + "region_code": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "region_id": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-int" + }, + "region_name": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "relay_url": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "stun_addresses": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-array_string" + } + } + }, + "codersdk.DeploymentConfig": { + "type": "object", + "properties": { + "access_url": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "address": { + "description": "DEPRECATED: Use HTTPAddress or TLS.Address instead.", + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "agent_fallback_troubleshooting_url": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "agent_stat_refresh_interval": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-time_Duration" + }, + "api_rate_limit": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-int" + }, + "audit_logging": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" + }, + "auto_import_templates": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-array_string" + }, + "autobuild_poll_interval": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-time_Duration" + }, + "browser_only": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" + }, + "cache_directory": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "derp": { + "$ref": "#/definitions/codersdk.DERP" + }, + "experimental": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" + }, + "gitauth": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-array_codersdk_GitAuthConfig" + }, + "http_address": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "in_memory_database": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" + }, + "max_token_lifetime": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-time_Duration" + }, + "metrics_cache_refresh_interval": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-time_Duration" + }, + "oauth2": { + "$ref": "#/definitions/codersdk.OAuth2Config" + }, + "oidc": { + "$ref": "#/definitions/codersdk.OIDCConfig" + }, + "pg_connection_url": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "pprof": { + "$ref": "#/definitions/codersdk.PprofConfig" + }, + "prometheus": { + "$ref": "#/definitions/codersdk.PrometheusConfig" + }, + "provisioner": { + "$ref": "#/definitions/codersdk.ProvisionerConfig" + }, + "proxy_trusted_headers": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-array_string" + }, + "proxy_trusted_origins": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-array_string" + }, + "scim_api_key": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "secure_auth_cookie": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" + }, + "ssh_keygen_algorithm": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "swagger": { + "$ref": "#/definitions/codersdk.SwaggerConfig" + }, + "telemetry": { + "$ref": "#/definitions/codersdk.TelemetryConfig" + }, + "tls": { + "$ref": "#/definitions/codersdk.TLSConfig" + }, + "trace": { + "$ref": "#/definitions/codersdk.TraceConfig" + }, + "update_check": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" + }, + "wildcard_access_url": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + } + } + }, + "codersdk.DeploymentConfigField-array_codersdk_GitAuthConfig": { + "type": "object", + "properties": { + "default": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.GitAuthConfig" + } + }, + "enterprise": { + "type": "boolean" + }, + "flag": { + "type": "string" + }, + "hidden": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "secret": { + "type": "boolean" + }, + "shorthand": { + "type": "string" + }, + "usage": { + "type": "string" + }, + "value": { + "$ref": "#/definitions/codersdk.GitAuthConfig" + } + } + }, + "codersdk.DeploymentConfigField-array_string": { + "type": "object", + "properties": { + "default": { + "type": "array", + "items": { + "type": "string" + } + }, + "enterprise": { + "type": "boolean" + }, + "flag": { + "type": "string" + }, + "hidden": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "secret": { + "type": "boolean" + }, + "shorthand": { + "type": "string" + }, + "usage": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "codersdk.DeploymentConfigField-bool": { + "type": "object", + "properties": { + "default": { + "type": "boolean" + }, + "enterprise": { + "type": "boolean" + }, + "flag": { + "type": "string" + }, + "hidden": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "secret": { + "type": "boolean" + }, + "shorthand": { + "type": "string" + }, + "usage": { + "type": "string" + }, + "value": { + "type": "boolean" + } + } + }, + "codersdk.DeploymentConfigField-int": { + "type": "object", + "properties": { + "default": { + "type": "integer" + }, + "enterprise": { + "type": "boolean" + }, + "flag": { + "type": "string" + }, + "hidden": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "secret": { + "type": "boolean" + }, + "shorthand": { + "type": "string" + }, + "usage": { + "type": "string" + }, + "value": { + "type": "integer" + } + } + }, + "codersdk.DeploymentConfigField-string": { + "type": "object", + "properties": { + "default": { + "type": "string" + }, + "enterprise": { + "type": "boolean" + }, + "flag": { + "type": "string" + }, + "hidden": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "secret": { + "type": "boolean" + }, + "shorthand": { + "type": "string" + }, + "usage": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "codersdk.DeploymentConfigField-time_Duration": { + "type": "object", + "properties": { + "default": { + "type": "integer" + }, + "enterprise": { + "type": "boolean" + }, + "flag": { + "type": "string" + }, + "hidden": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "secret": { + "type": "boolean" + }, + "shorthand": { + "type": "string" + }, + "usage": { + "type": "string" + }, + "value": { + "type": "integer" + } + } + }, + "codersdk.GetAppHostResponse": { + "type": "object", + "properties": { + "host": { + "description": "Host is the externally accessible URL for the Coder instance.", + "type": "string" + } + } + }, + "codersdk.GitAuthConfig": { "type": "object", "properties": { - "organization_id": { - "description": "OrganizationID (optional) adds the set constraint to all resources owned by a given organization.", + "auth_url": { "type": "string" }, - "owner_id": { - "description": "OwnerID (optional) adds the set constraint to all resources owned by a given user.", + "client_id": { "type": "string" }, - "resource_id": { - "description": "ResourceID (optional) reduces the set to a singular resource. This assigns\na resource ID to the resource type, eg: a single workspace.\nThe rbac library will not fetch the resource from the database, so if you\nare using this option, you should also set the owner ID and organization ID\nif possible. Be as specific as possible using all the fields relevant.", + "id": { "type": "string" }, - "resource_type": { - "description": "ResourceType is the name of the resource.\n` + "`" + `./coderd/rbac/object.go` + "`" + ` has the list of valid resource types.", + "no_refresh": { + "type": "boolean" + }, + "regex": { + "type": "string" + }, + "scopes": { + "type": "array", + "items": { + "type": "string" + } + }, + "token_url": { + "type": "string" + }, + "type": { + "type": "string" + }, + "validate_url": { "type": "string" } } }, - "codersdk.AuthorizationRequest": { + "codersdk.Healthcheck": { "type": "object", "properties": { - "checks": { - "description": "Checks is a map keyed with an arbitrary string to a permission check.\nThe key can be any string that is helpful to the caller, and allows\nmultiple permission checks to be run in a single request.\nThe key ensures that each permission check has the same key in the\nresponse.", - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/codersdk.AuthorizationCheck" - } + "interval": { + "description": "Interval specifies the seconds between each health check.", + "type": "integer" + }, + "threshold": { + "description": "Threshold specifies the number of consecutive failed health checks before returning \"unhealthy\".", + "type": "integer" + }, + "url": { + "description": "URL specifies the endpoint to check for the app health.", + "type": "string" } } }, - "codersdk.AuthorizationResponse": { + "codersdk.OAuth2Config": { "type": "object", - "additionalProperties": { - "type": "boolean" + "properties": { + "github": { + "$ref": "#/definitions/codersdk.OAuth2GithubConfig" + } } }, - "codersdk.BuildInfoResponse": { + "codersdk.OAuth2GithubConfig": { "type": "object", "properties": { - "external_url": { - "description": "ExternalURL references the current Coder version.\nFor production builds, this will link directly to a release. For development builds, this will link to a commit.", - "type": "string" + "allow_everyone": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" }, - "version": { - "description": "Version returns the semantic version of the build.", - "type": "string" + "allow_signups": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" + }, + "allowed_orgs": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-array_string" + }, + "allowed_teams": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-array_string" + }, + "client_id": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "client_secret": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "enterprise_base_url": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" } } }, - "codersdk.CreateParameterRequest": { - "description": "CreateParameterRequest is a structure used to create a new parameter value for a scope.", + "codersdk.OIDCConfig": { "type": "object", - "required": [ - "destination_scheme", - "name", - "source_scheme", - "source_value" - ], "properties": { - "copy_from_parameter": { - "description": "CloneID allows copying the value of another parameter.\nThe other param must be related to the same template_id for this to\nsucceed.\nNo other fields are required if using this, as all fields will be copied\nfrom the other parameter.", + "allow_signups": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" + }, + "client_id": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "client_secret": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "email_domain": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-array_string" + }, + "ignore_email_verified": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" + }, + "issuer_url": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "scopes": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-array_string" + } + } + }, + "codersdk.Parameter": { + "description": "Parameter represents a set value for the scope.", + "type": "object", + "properties": { + "created_at": { "type": "string" }, "destination_scheme": { "type": "string", "enum": [ + "none", "environment_variable", "provisioner_variable" ] }, + "id": { + "type": "string", + "format": "uuid" + }, "name": { "type": "string" }, + "scope": { + "type": "string", + "enum": [ + "template", + "workspace", + "import_job" + ] + }, + "scope_id": { + "type": "string", + "format": "uuid" + }, "source_scheme": { "type": "string", "enum": [ + "none", "data" ] }, - "source_value": { + "updated_at": { "type": "string" } } }, - "codersdk.CreateTemplateRequest": { + "codersdk.PprofConfig": { "type": "object", - "required": [ - "name", - "template_version_id" - ], "properties": { - "allow_user_cancel_workspace_jobs": { - "description": "Allow users to cancel in-progress workspace jobs.\n*bool as the default value is \"true\".", - "type": "boolean" - }, - "default_ttl_ms": { - "description": "DefaultTTLMillis allows optionally specifying the default TTL\nfor all workspaces created from this template.", - "type": "integer" - }, - "description": { - "description": "Description is a description of what the template contains. It must be\nless than 128 bytes.", - "type": "string" - }, - "display_name": { - "description": "DisplayName is the displayed name of the template.", - "type": "string" - }, - "icon": { - "description": "Icon is a relative path or external URL that specifies\nan icon to be displayed in the dashboard.", - "type": "string" - }, - "name": { - "description": "Name is the name of the template.", - "type": "string" - }, - "parameter_values": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.CreateParameterRequest" - } + "address": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" }, - "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" + "enable": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" } } }, - "codersdk.DERPRegion": { + "codersdk.PrometheusConfig": { "type": "object", "properties": { - "latency_ms": { - "type": "number" + "address": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" }, - "preferred": { - "type": "boolean" + "enable": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" } } }, - "codersdk.GetAppHostResponse": { - "type": "object", - "properties": { - "host": { - "description": "Host is the externally accessible URL for the Coder instance.", - "type": "string" - } - } - }, - "codersdk.Healthcheck": { + "codersdk.ProvisionerConfig": { "type": "object", "properties": { - "interval": { - "description": "Interval specifies the seconds between each health check.", - "type": "integer" + "daemon_poll_interval": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-time_Duration" }, - "threshold": { - "description": "Threshold specifies the number of consecutive failed health checks before returning \"unhealthy\".", - "type": "integer" + "daemon_poll_jitter": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-time_Duration" }, - "url": { - "description": "URL specifies the endpoint to check for the app health.", - "type": "string" - } - } - }, - "codersdk.NullTime": { - "type": "object", - "properties": { - "time": { - "type": "string" + "daemons": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-int" }, - "valid": { - "description": "Valid is true if Time is not NULL", - "type": "boolean" + "force_cancel_interval": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-time_Duration" } } }, @@ -1103,6 +2132,74 @@ const docTemplate = `{ } } }, + "codersdk.Role": { + "type": "object", + "properties": { + "display_name": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "codersdk.SwaggerConfig": { + "type": "object", + "properties": { + "enable": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" + } + } + }, + "codersdk.TLSConfig": { + "type": "object", + "properties": { + "address": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "cert_file": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-array_string" + }, + "client_auth": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "client_ca_file": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "client_cert_file": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "client_key_file": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "enable": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" + }, + "key_file": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-array_string" + }, + "min_version": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "redirect_http": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" + } + } + }, + "codersdk.TelemetryConfig": { + "type": "object", + "properties": { + "enable": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" + }, + "trace": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" + }, + "url": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + } + } + }, "codersdk.Template": { "type": "object", "properties": { @@ -1171,6 +2268,20 @@ const docTemplate = `{ "$ref": "#/definitions/codersdk.TransitionStats" } }, + "codersdk.TraceConfig": { + "type": "object", + "properties": { + "capture_logs": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" + }, + "enable": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" + }, + "honeycomb_api_key": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + } + } + }, "codersdk.TransitionStats": { "type": "object", "properties": { @@ -1225,6 +2336,58 @@ const docTemplate = `{ } } }, + "codersdk.UploadResponse": { + "type": "object", + "properties": { + "hash": { + "type": "string" + } + } + }, + "codersdk.User": { + "type": "object", + "required": [ + "created_at", + "email", + "id", + "username" + ], + "properties": { + "avatar_url": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "email": { + "type": "string" + }, + "id": { + "type": "string" + }, + "last_seen_at": { + "type": "string" + }, + "organization_ids": { + "type": "array", + "items": { + "type": "string" + } + }, + "roles": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Role" + } + }, + "status": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, "codersdk.ValidationError": { "type": "object", "required": [ @@ -1433,7 +2596,8 @@ const docTemplate = `{ "type": "integer" }, "deadline": { - "$ref": "#/definitions/codersdk.NullTime" + "type": "string", + "format": "date-time" }, "id": { "type": "string", @@ -1587,6 +2751,9 @@ const docTemplate = `{ } } } + }, + "netip.Addr": { + "type": "object" } }, "securityDefinitions": { diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index f33bec806f70a..ef30670b3a406 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -79,6 +79,84 @@ } } }, + "/audit": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Audit"], + "summary": "Get audit logs", + "operationId": "get-audit-logs", + "parameters": [ + { + "type": "string", + "description": "Search query", + "name": "q", + "in": "query", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "After ID", + "name": "after_id", + "in": "query" + }, + { + "type": "integer", + "description": "Page limit", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "description": "Page offset", + "name": "offset", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.AuditLogResponse" + } + } + } + } + }, + "/audit/testgenerate": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "tags": ["Audit"], + "summary": "Generate fake audit log", + "operationId": "generate-fake-audit-logs", + "parameters": [ + { + "description": "Audit log request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateTestAuditLogRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, "/authcheck": { "post": { "security": [ @@ -128,6 +206,27 @@ } } }, + "/config/deployment": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["General"], + "summary": "Get deployment config", + "operationId": "get-deployment-config", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.DeploymentConfig" + } + } + } + } + }, "/csp/reports": { "post": { "security": [ @@ -158,6 +257,73 @@ } } }, + "/files": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "description": "Notice: Swagger 2.0 doesn't support file upload with a `content-type` different than `application/x-www-form-urlencoded`.", + "consumes": ["application/x-tar"], + "produces": ["application/json"], + "tags": ["Files"], + "summary": "Upload file", + "operationId": "update-file", + "parameters": [ + { + "type": "string", + "default": "application/x-tar", + "description": "Content-Type must be `application/x-tar`", + "name": "Content-Type", + "in": "header", + "required": true + }, + { + "type": "file", + "description": "File to be uploaded", + "name": "file", + "in": "formData", + "required": true + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.UploadResponse" + } + } + } + } + }, + "/files/{fileID}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": ["Files"], + "summary": "Get file by ID", + "operationId": "get-file-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "File ID", + "name": "fileID", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, "/organizations/{organization-id}/templates/": { "post": { "security": [ @@ -308,6 +474,141 @@ } } }, + "/parameters/{scope}/{id}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Parameters"], + "summary": "Get parameters", + "operationId": "get-parameters", + "parameters": [ + { + "enum": ["template", "workspace", "import_job"], + "type": "string", + "description": "Scope", + "name": "scope", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Parameter" + } + } + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Parameters"], + "summary": "Create parameter", + "operationId": "create-parameter", + "parameters": [ + { + "description": "Parameter request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateParameterRequest" + } + }, + { + "enum": ["template", "workspace", "import_job"], + "type": "string", + "description": "Scope", + "name": "scope", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.Parameter" + } + } + } + } + }, + "/parameters/{scope}/{id}/{name}": { + "delete": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Parameters"], + "summary": "Delete parameter", + "operationId": "delete-parameter", + "parameters": [ + { + "enum": ["template", "workspace", "import_job"], + "type": "string", + "description": "Scope", + "name": "scope", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Name", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, "/templates/{id}": { "get": { "security": [ @@ -317,8 +618,8 @@ ], "produces": ["application/json"], "tags": ["Templates"], - "summary": "Update template metadata by ID", - "operationId": "update-template-metadata", + "summary": "Get template metadata by ID", + "operationId": "get-template-metadata-by-id", "parameters": [ { "type": "string", @@ -366,6 +667,35 @@ } } } + }, + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Update template metadata by ID", + "operationId": "update-template-metadata", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Template" + } + } + } } }, "/updatecheck": { @@ -726,10 +1056,103 @@ } } }, - "codersdk.AuthorizationCheck": { - "description": "AuthorizationCheck is used to check if the currently authenticated user (or the specified user) can do a given action to a given set of objects.", + "codersdk.AuditDiff": { "type": "object", - "properties": { + "additionalProperties": { + "$ref": "#/definitions/codersdk.AuditDiffField" + } + }, + "codersdk.AuditDiffField": { + "type": "object", + "properties": { + "new": {}, + "old": {}, + "secret": { + "type": "boolean" + } + } + }, + "codersdk.AuditLog": { + "type": "object", + "properties": { + "action": { + "type": "string" + }, + "additional_fields": { + "type": "array", + "items": { + "type": "integer" + } + }, + "description": { + "type": "string" + }, + "diff": { + "$ref": "#/definitions/codersdk.AuditDiff" + }, + "id": { + "type": "string" + }, + "ip": { + "$ref": "#/definitions/netip.Addr" + }, + "is_deleted": { + "type": "boolean" + }, + "organization_id": { + "type": "string" + }, + "request_id": { + "type": "string" + }, + "resource_icon": { + "type": "string" + }, + "resource_id": { + "type": "string" + }, + "resource_link": { + "type": "string" + }, + "resource_target": { + "description": "ResourceTarget is the name of the resource.", + "type": "string" + }, + "resource_type": { + "type": "string" + }, + "status_code": { + "type": "integer" + }, + "time": { + "type": "string" + }, + "user": { + "$ref": "#/definitions/codersdk.User" + }, + "user_agent": { + "type": "string" + } + } + }, + "codersdk.AuditLogResponse": { + "type": "object", + "properties": { + "audit_logs": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.AuditLog" + } + }, + "count": { + "type": "integer" + } + } + }, + "codersdk.AuthorizationCheck": { + "description": "AuthorizationCheck is used to check if the currently authenticated user (or the specified user) can do a given action to a given set of objects.", + "type": "object", + "properties": { "action": { "type": "string", "enum": ["create", "read", "update", "delete"] @@ -809,14 +1232,14 @@ }, "destination_scheme": { "type": "string", - "enum": ["environment_variable", "provisioner_variable"] + "enum": ["none", "environment_variable", "provisioner_variable"] }, "name": { "type": "string" }, "source_scheme": { "type": "string", - "enum": ["data"] + "enum": ["none", "data"] }, "source_value": { "type": "string" @@ -863,6 +1286,57 @@ } } }, + "codersdk.CreateTestAuditLogRequest": { + "type": "object", + "properties": { + "action": { + "type": "string", + "enum": ["create", "write", "delete", "start", "stop"] + }, + "resource_id": { + "type": "string" + }, + "resource_type": { + "type": "string", + "enum": [ + "organization", + "template", + "template_version", + "user", + "workspace", + "workspace_build", + "git_ssh_key", + "api_key", + "group" + ] + }, + "time": { + "type": "string" + } + } + }, + "codersdk.DERP": { + "type": "object", + "properties": { + "config": { + "$ref": "#/definitions/codersdk.DERPConfig" + }, + "server": { + "$ref": "#/definitions/codersdk.DERPServerConfig" + } + } + }, + "codersdk.DERPConfig": { + "type": "object", + "properties": { + "path": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "url": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + } + } + }, "codersdk.DERPRegion": { "type": "object", "properties": { @@ -874,6 +1348,335 @@ } } }, + "codersdk.DERPServerConfig": { + "type": "object", + "properties": { + "enable": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" + }, + "region_code": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "region_id": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-int" + }, + "region_name": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "relay_url": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "stun_addresses": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-array_string" + } + } + }, + "codersdk.DeploymentConfig": { + "type": "object", + "properties": { + "access_url": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "address": { + "description": "DEPRECATED: Use HTTPAddress or TLS.Address instead.", + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "agent_fallback_troubleshooting_url": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "agent_stat_refresh_interval": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-time_Duration" + }, + "api_rate_limit": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-int" + }, + "audit_logging": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" + }, + "auto_import_templates": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-array_string" + }, + "autobuild_poll_interval": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-time_Duration" + }, + "browser_only": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" + }, + "cache_directory": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "derp": { + "$ref": "#/definitions/codersdk.DERP" + }, + "experimental": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" + }, + "gitauth": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-array_codersdk_GitAuthConfig" + }, + "http_address": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "in_memory_database": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" + }, + "max_token_lifetime": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-time_Duration" + }, + "metrics_cache_refresh_interval": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-time_Duration" + }, + "oauth2": { + "$ref": "#/definitions/codersdk.OAuth2Config" + }, + "oidc": { + "$ref": "#/definitions/codersdk.OIDCConfig" + }, + "pg_connection_url": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "pprof": { + "$ref": "#/definitions/codersdk.PprofConfig" + }, + "prometheus": { + "$ref": "#/definitions/codersdk.PrometheusConfig" + }, + "provisioner": { + "$ref": "#/definitions/codersdk.ProvisionerConfig" + }, + "proxy_trusted_headers": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-array_string" + }, + "proxy_trusted_origins": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-array_string" + }, + "scim_api_key": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "secure_auth_cookie": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" + }, + "ssh_keygen_algorithm": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "swagger": { + "$ref": "#/definitions/codersdk.SwaggerConfig" + }, + "telemetry": { + "$ref": "#/definitions/codersdk.TelemetryConfig" + }, + "tls": { + "$ref": "#/definitions/codersdk.TLSConfig" + }, + "trace": { + "$ref": "#/definitions/codersdk.TraceConfig" + }, + "update_check": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" + }, + "wildcard_access_url": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + } + } + }, + "codersdk.DeploymentConfigField-array_codersdk_GitAuthConfig": { + "type": "object", + "properties": { + "default": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.GitAuthConfig" + } + }, + "enterprise": { + "type": "boolean" + }, + "flag": { + "type": "string" + }, + "hidden": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "secret": { + "type": "boolean" + }, + "shorthand": { + "type": "string" + }, + "usage": { + "type": "string" + }, + "value": { + "$ref": "#/definitions/codersdk.GitAuthConfig" + } + } + }, + "codersdk.DeploymentConfigField-array_string": { + "type": "object", + "properties": { + "default": { + "type": "array", + "items": { + "type": "string" + } + }, + "enterprise": { + "type": "boolean" + }, + "flag": { + "type": "string" + }, + "hidden": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "secret": { + "type": "boolean" + }, + "shorthand": { + "type": "string" + }, + "usage": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "codersdk.DeploymentConfigField-bool": { + "type": "object", + "properties": { + "default": { + "type": "boolean" + }, + "enterprise": { + "type": "boolean" + }, + "flag": { + "type": "string" + }, + "hidden": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "secret": { + "type": "boolean" + }, + "shorthand": { + "type": "string" + }, + "usage": { + "type": "string" + }, + "value": { + "type": "boolean" + } + } + }, + "codersdk.DeploymentConfigField-int": { + "type": "object", + "properties": { + "default": { + "type": "integer" + }, + "enterprise": { + "type": "boolean" + }, + "flag": { + "type": "string" + }, + "hidden": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "secret": { + "type": "boolean" + }, + "shorthand": { + "type": "string" + }, + "usage": { + "type": "string" + }, + "value": { + "type": "integer" + } + } + }, + "codersdk.DeploymentConfigField-string": { + "type": "object", + "properties": { + "default": { + "type": "string" + }, + "enterprise": { + "type": "boolean" + }, + "flag": { + "type": "string" + }, + "hidden": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "secret": { + "type": "boolean" + }, + "shorthand": { + "type": "string" + }, + "usage": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "codersdk.DeploymentConfigField-time_Duration": { + "type": "object", + "properties": { + "default": { + "type": "integer" + }, + "enterprise": { + "type": "boolean" + }, + "flag": { + "type": "string" + }, + "hidden": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "secret": { + "type": "boolean" + }, + "shorthand": { + "type": "string" + }, + "usage": { + "type": "string" + }, + "value": { + "type": "integer" + } + } + }, "codersdk.GetAppHostResponse": { "type": "object", "properties": { @@ -883,6 +1686,41 @@ } } }, + "codersdk.GitAuthConfig": { + "type": "object", + "properties": { + "auth_url": { + "type": "string" + }, + "client_id": { + "type": "string" + }, + "id": { + "type": "string" + }, + "no_refresh": { + "type": "boolean" + }, + "regex": { + "type": "string" + }, + "scopes": { + "type": "array", + "items": { + "type": "string" + } + }, + "token_url": { + "type": "string" + }, + "type": { + "type": "string" + }, + "validate_url": { + "type": "string" + } + } + }, "codersdk.Healthcheck": { "type": "object", "properties": { @@ -900,15 +1738,137 @@ } } }, - "codersdk.NullTime": { + "codersdk.OAuth2Config": { "type": "object", "properties": { - "time": { + "github": { + "$ref": "#/definitions/codersdk.OAuth2GithubConfig" + } + } + }, + "codersdk.OAuth2GithubConfig": { + "type": "object", + "properties": { + "allow_everyone": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" + }, + "allow_signups": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" + }, + "allowed_orgs": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-array_string" + }, + "allowed_teams": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-array_string" + }, + "client_id": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "client_secret": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "enterprise_base_url": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + } + } + }, + "codersdk.OIDCConfig": { + "type": "object", + "properties": { + "allow_signups": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" + }, + "client_id": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "client_secret": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "email_domain": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-array_string" + }, + "ignore_email_verified": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" + }, + "issuer_url": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "scopes": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-array_string" + } + } + }, + "codersdk.Parameter": { + "description": "Parameter represents a set value for the scope.", + "type": "object", + "properties": { + "created_at": { "type": "string" }, - "valid": { - "description": "Valid is true if Time is not NULL", - "type": "boolean" + "destination_scheme": { + "type": "string", + "enum": ["none", "environment_variable", "provisioner_variable"] + }, + "id": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "scope": { + "type": "string", + "enum": ["template", "workspace", "import_job"] + }, + "scope_id": { + "type": "string", + "format": "uuid" + }, + "source_scheme": { + "type": "string", + "enum": ["none", "data"] + }, + "updated_at": { + "type": "string" + } + } + }, + "codersdk.PprofConfig": { + "type": "object", + "properties": { + "address": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "enable": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" + } + } + }, + "codersdk.PrometheusConfig": { + "type": "object", + "properties": { + "address": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "enable": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" + } + } + }, + "codersdk.ProvisionerConfig": { + "type": "object", + "properties": { + "daemon_poll_interval": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-time_Duration" + }, + "daemon_poll_jitter": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-time_Duration" + }, + "daemons": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-int" + }, + "force_cancel_interval": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-time_Duration" } } }, @@ -979,6 +1939,74 @@ } } }, + "codersdk.Role": { + "type": "object", + "properties": { + "display_name": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "codersdk.SwaggerConfig": { + "type": "object", + "properties": { + "enable": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" + } + } + }, + "codersdk.TLSConfig": { + "type": "object", + "properties": { + "address": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "cert_file": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-array_string" + }, + "client_auth": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "client_ca_file": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "client_cert_file": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "client_key_file": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "enable": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" + }, + "key_file": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-array_string" + }, + "min_version": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + }, + "redirect_http": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" + } + } + }, + "codersdk.TelemetryConfig": { + "type": "object", + "properties": { + "enable": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" + }, + "trace": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" + }, + "url": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + } + } + }, "codersdk.Template": { "type": "object", "properties": { @@ -1047,6 +2075,20 @@ "$ref": "#/definitions/codersdk.TransitionStats" } }, + "codersdk.TraceConfig": { + "type": "object", + "properties": { + "capture_logs": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" + }, + "enable": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-bool" + }, + "honeycomb_api_key": { + "$ref": "#/definitions/codersdk.DeploymentConfigField-string" + } + } + }, "codersdk.TransitionStats": { "type": "object", "properties": { @@ -1101,6 +2143,53 @@ } } }, + "codersdk.UploadResponse": { + "type": "object", + "properties": { + "hash": { + "type": "string" + } + } + }, + "codersdk.User": { + "type": "object", + "required": ["created_at", "email", "id", "username"], + "properties": { + "avatar_url": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "email": { + "type": "string" + }, + "id": { + "type": "string" + }, + "last_seen_at": { + "type": "string" + }, + "organization_ids": { + "type": "array", + "items": { + "type": "string" + } + }, + "roles": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Role" + } + }, + "status": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, "codersdk.ValidationError": { "type": "object", "required": ["detail", "field"], @@ -1306,7 +2395,8 @@ "type": "integer" }, "deadline": { - "$ref": "#/definitions/codersdk.NullTime" + "type": "string", + "format": "date-time" }, "id": { "type": "string", @@ -1452,6 +2542,9 @@ } } } + }, + "netip.Addr": { + "type": "object" } }, "securityDefinitions": { diff --git a/coderd/audit.go b/coderd/audit.go index eaac13a66cfbb..72b27690fb179 100644 --- a/coderd/audit.go +++ b/coderd/audit.go @@ -24,6 +24,17 @@ import ( "github.com/coder/coder/codersdk" ) +// @Summary Get audit logs +// @ID get-audit-logs +// @Security CoderSessionToken +// @Produce json +// @Tags Audit +// @Param q query string true "Search query" +// @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 {object} codersdk.AuditLogResponse +// @Router /audit [get] func (api *API) auditLogs(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() if !api.Authorize(r, rbac.ActionRead, rbac.ResourceAuditLog) { @@ -77,6 +88,14 @@ func (api *API) auditLogs(rw http.ResponseWriter, r *http.Request) { }) } +// @Summary Generate fake audit log +// @ID generate-fake-audit-logs +// @Security CoderSessionToken +// @Accept json +// @Tags Audit +// @Param request body codersdk.CreateTestAuditLogRequest true "Audit log request" +// @Success 204 +// @Router /audit/testgenerate [post] func (api *API) generateFakeAuditLog(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() if !api.Authorize(r, rbac.ActionCreate, rbac.ResourceAuditLog) { diff --git a/coderd/deploymentconfig.go b/coderd/deploymentconfig.go index d68332c9089f7..9b84120d77af5 100644 --- a/coderd/deploymentconfig.go +++ b/coderd/deploymentconfig.go @@ -7,6 +7,13 @@ import ( "github.com/coder/coder/coderd/rbac" ) +// @Summary Get deployment config +// @ID get-deployment-config +// @Security CoderSessionToken +// @Produce json +// @Tags General +// @Success 200 {object} codersdk.DeploymentConfig +// @Router /config/deployment [get] func (api *API) deploymentConfig(rw http.ResponseWriter, r *http.Request) { if !api.Authorize(r, rbac.ActionRead, rbac.ResourceDeploymentConfig) { httpapi.Forbidden(rw) diff --git a/coderd/files.go b/coderd/files.go index 8d01745f919c6..5178f61a9d00d 100644 --- a/coderd/files.go +++ b/coderd/files.go @@ -23,6 +23,17 @@ const ( tarMimeType = "application/x-tar" ) +// @Summary Upload file +// @Description Notice: Swagger 2.0 doesn't support file upload with a `content-type` different than `application/x-www-form-urlencoded`. +// @ID update-file +// @Security CoderSessionToken +// @Produce json +// @Accept application/x-tar +// @Tags Files +// @Param Content-Type header string true "Content-Type must be `application/x-tar`" default(application/x-tar) +// @Param file formData file true "File to be uploaded" +// @Success 201 {object} codersdk.UploadResponse +// @Router /files [post] func (api *API) postFile(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() apiKey := httpmw.APIKey(r) @@ -88,6 +99,13 @@ func (api *API) postFile(rw http.ResponseWriter, r *http.Request) { }) } +// @Summary Get file by ID +// @ID get-file-by-id +// @Security CoderSessionToken +// @Tags Files +// @Param fileID path string true "File ID" format(uuid) +// @Success 200 +// @Router /files/{fileID} [get] func (api *API) fileByID(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() diff --git a/coderd/parameters.go b/coderd/parameters.go index ba3fd2349f48a..29adb4bf5e43b 100644 --- a/coderd/parameters.go +++ b/coderd/parameters.go @@ -18,6 +18,17 @@ import ( "github.com/coder/coder/codersdk" ) +// @Summary Create parameter +// @ID create-parameter +// @Security CoderSessionToken +// @Accept json +// @Produce json +// @Tags Parameters +// @Param request body codersdk.CreateParameterRequest true "Parameter request" +// @Param scope path string true "Scope" Enums(template,workspace,import_job) +// @Param id path string true "ID" format(uuid) +// @Success 201 {object} codersdk.Parameter +// @Router /parameters/{scope}/{id} [post] func (api *API) postParameter(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() scope, scopeID, valid := readScopeAndID(ctx, rw, r) @@ -78,6 +89,15 @@ func (api *API) postParameter(rw http.ResponseWriter, r *http.Request) { httpapi.Write(ctx, rw, http.StatusCreated, convertParameterValue(parameterValue)) } +// @Summary Get parameters +// @ID get-parameters +// @Security CoderSessionToken +// @Produce json +// @Tags Parameters +// @Param scope path string true "Scope" Enums(template,workspace,import_job) +// @Param id path string true "ID" format(uuid) +// @Success 200 {array} codersdk.Parameter +// @Router /parameters/{scope}/{id} [get] func (api *API) parameters(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() scope, scopeID, valid := readScopeAndID(ctx, rw, r) @@ -116,6 +136,16 @@ func (api *API) parameters(rw http.ResponseWriter, r *http.Request) { httpapi.Write(ctx, rw, http.StatusOK, apiParameterValues) } +// @Summary Delete parameter +// @ID delete-parameter +// @Security CoderSessionToken +// @Produce json +// @Tags Parameters +// @Param scope path string true "Scope" Enums(template,workspace,import_job) +// @Param id path string true "ID" format(uuid) +// @Param name path string true "Name" +// @Success 200 {object} codersdk.Response +// @Router /parameters/{scope}/{id}/{name} [delete] func (api *API) deleteParameter(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() scope, scopeID, valid := readScopeAndID(ctx, rw, r) diff --git a/coderd/templates.go b/coderd/templates.go index 74e3560703131..662a3069683c7 100644 --- a/coderd/templates.go +++ b/coderd/templates.go @@ -478,7 +478,7 @@ func (api *API) templateByOrganizationAndName(rw http.ResponseWriter, r *http.Re // @Tags Templates // @Param id path string true "Template ID" format(uuid) // @Success 200 {object} codersdk.Template -// @Router /templates/{id} [get] +// @Router /templates/{id} [patch] func (api *API) patchTemplateMeta(rw http.ResponseWriter, r *http.Request) { var ( ctx = r.Context() diff --git a/codersdk/audit.go b/codersdk/audit.go index e3d25851ea89f..da8f88df04ade 100644 --- a/codersdk/audit.go +++ b/codersdk/audit.go @@ -121,8 +121,8 @@ type AuditLogResponse struct { } type CreateTestAuditLogRequest struct { - Action AuditAction `json:"action,omitempty"` - ResourceType ResourceType `json:"resource_type,omitempty"` + 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"` } diff --git a/codersdk/parameters.go b/codersdk/parameters.go index c813096412a11..92717e55e1651 100644 --- a/codersdk/parameters.go +++ b/codersdk/parameters.go @@ -49,13 +49,15 @@ type ComputedParameter struct { } // Parameter represents a set value for the scope. +// +// @Description Parameter represents a set value for the scope. type Parameter struct { - ID uuid.UUID `json:"id" table:"id"` - Scope ParameterScope `json:"scope" table:"scope"` - ScopeID uuid.UUID `json:"scope_id" table:"scope id"` + ID uuid.UUID `json:"id" table:"id" format:"uuid"` + Scope ParameterScope `json:"scope" table:"scope" enums:"template,workspace,import_job"` + ScopeID uuid.UUID `json:"scope_id" table:"scope id" format:"uuid"` Name string `json:"name" table:"name"` - SourceScheme ParameterSourceScheme `json:"source_scheme" table:"source scheme" validate:"ne=none"` - DestinationScheme ParameterDestinationScheme `json:"destination_scheme" table:"destination scheme" validate:"ne=none"` + SourceScheme ParameterSourceScheme `json:"source_scheme" table:"source scheme" validate:"ne=none" enums:"none,data"` + DestinationScheme ParameterDestinationScheme `json:"destination_scheme" table:"destination scheme" validate:"ne=none" enums:"none,environment_variable,provisioner_variable"` CreatedAt time.Time `json:"created_at" table:"created at"` UpdatedAt time.Time `json:"updated_at" table:"updated at"` } @@ -96,8 +98,8 @@ type CreateParameterRequest struct { Name string `json:"name" validate:"required"` SourceValue string `json:"source_value" validate:"required"` - SourceScheme ParameterSourceScheme `json:"source_scheme" validate:"oneof=data,required"` - DestinationScheme ParameterDestinationScheme `json:"destination_scheme" validate:"oneof=environment_variable provisioner_variable,required"` + SourceScheme ParameterSourceScheme `json:"source_scheme" validate:"oneof=data,required" enums:"none,data"` + DestinationScheme ParameterDestinationScheme `json:"destination_scheme" validate:"oneof=environment_variable provisioner_variable,required" enums:"none,environment_variable,provisioner_variable"` } func (c *Client) CreateParameter(ctx context.Context, scope ParameterScope, id uuid.UUID, req CreateParameterRequest) (Parameter, error) { diff --git a/codersdk/workspacebuilds.go b/codersdk/workspacebuilds.go index 80055484df0f6..5281710a797b0 100644 --- a/codersdk/workspacebuilds.go +++ b/codersdk/workspacebuilds.go @@ -67,7 +67,7 @@ type WorkspaceBuild struct { Job ProvisionerJob `json:"job"` Reason BuildReason `db:"reason" json:"reason"` Resources []WorkspaceResource `json:"resources"` - Deadline NullTime `json:"deadline,omitempty"` + Deadline NullTime `json:"deadline,omitempty" swaggertype:"string" format:"date-time"` Status WorkspaceStatus `json:"status" enums:"pending,starting,running,stopping,stopped,failed,canceling,canceled,deleting,deleted"` DailyCost int32 `json:"daily_cost"` } diff --git a/docs/api/audit.md b/docs/api/audit.md new file mode 100644 index 0000000000000..8b3946c715665 --- /dev/null +++ b/docs/api/audit.md @@ -0,0 +1,129 @@ +# Audit + +> This page is incomplete, stay tuned. + +## Get audit logs + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/audit?q=string \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /audit` + +### Parameters + +| Name | In | Type | Required | Description | +| ---------- | ----- | ------------ | -------- | ------------ | +| `q` | query | string | true | Search query | +| `after_id` | query | string(uuid) | false | After ID | +| `limit` | query | integer | false | Page limit | +| `offset` | query | integer | false | Page offset | + +### Example responses + +> 200 Response + +```json +{ + "audit_logs": [ + { + "action": "string", + "additional_fields": [0], + "description": "string", + "diff": { + "property1": { + "new": null, + "old": null, + "secret": true + }, + "property2": { + "new": null, + "old": null, + "secret": true + } + }, + "id": "string", + "ip": {}, + "is_deleted": true, + "organization_id": "string", + "request_id": "string", + "resource_icon": "string", + "resource_id": "string", + "resource_link": "string", + "resource_target": "string", + "resource_type": "string", + "status_code": 0, + "time": "string", + "user": { + "avatar_url": "string", + "created_at": "string", + "email": "string", + "id": "string", + "last_seen_at": "string", + "organization_ids": ["string"], + "roles": [ + { + "display_name": "string", + "name": "string" + } + ], + "status": "string", + "username": "string" + }, + "user_agent": "string" + } + ], + "count": 0 +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ---------------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.AuditLogResponse](schemas.md#codersdkauditlogresponse) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Generate fake audit log + +### Code samples + +```shell +# Example request using curl +curl -X POST http://coder-server:8080/api/v2/audit/testgenerate \ + -H 'Content-Type: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`POST /audit/testgenerate` + +> Body parameter + +```json +{ + "action": "create", + "resource_id": "string", + "resource_type": "organization", + "time": "string" +} +``` + +### Parameters + +| Name | In | Type | Required | Description | +| ------ | ---- | ---------------------------------------------------------------------------------- | -------- | ----------------- | +| `body` | body | [codersdk.CreateTestAuditLogRequest](schemas.md#codersdkcreatetestauditlogrequest) | true | Audit log request | + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | --------------------------------------------------------------- | ----------- | ------ | +| 204 | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) | No Content | | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. diff --git a/docs/api/files.md b/docs/api/files.md new file mode 100644 index 0000000000000..85cb46bcdf74b --- /dev/null +++ b/docs/api/files.md @@ -0,0 +1,77 @@ +# Files + +> This page is incomplete, stay tuned. + +## Upload file + +### Code samples + +```shell +# Example request using curl +curl -X POST http://coder-server:8080/api/v2/files \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/x-tar' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`POST /files` + +Notice: Swagger 2.0 doesn't support file upload with a `content-type` different than `application/x-www-form-urlencoded`. + +> Body parameter + +```yaml +file: string +``` + +### Parameters + +| Name | In | Type | Required | Description | +| -------------- | ------ | -------------- | -------- | ---------------------------------------- | +| `Content-Type` | header | string | true | Content-Type must be `application/x-tar` | +| `body` | body | object | true | | +| `» file` | body | string(binary) | true | File to be uploaded | + +### Example responses + +> 201 Response + +```json +{ + "hash": "string" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------------ | ----------- | ------------------------------------------------------------ | +| 201 | [Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) | Created | [codersdk.UploadResponse](schemas.md#codersdkuploadresponse) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Get file by ID + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/files/{fileID} \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /files/{fileID}` + +### Parameters + +| Name | In | Type | Required | Description | +| -------- | ---- | ------------ | -------- | ----------- | +| `fileID` | path | string(uuid) | true | File 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 by means of one of the following methods: **CoderSessionToken**. diff --git a/docs/api/general.md b/docs/api/general.md index 8d5ef5dad967d..f8293d32c8709 100644 --- a/docs/api/general.md +++ b/docs/api/general.md @@ -37,8 +37,6 @@ curl -X GET http://coder-server:8080/api/v2/ \ | ------ | ------------------------------------------------------- | ----------- | ------------------------------------------------ | | 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.Response](schemas.md#codersdkresponse) | -undefined - ## Build info ### Code samples @@ -68,7 +66,864 @@ curl -X GET http://coder-server:8080/api/v2/buildinfo \ | ------ | ------------------------------------------------------- | ----------- | ------------------------------------------------------------------ | | 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.BuildInfoResponse](schemas.md#codersdkbuildinforesponse) | -undefined +## Get deployment config + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/config/deployment \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /config/deployment` + +### Example responses + +> 200 Response + +```json +{ + "access_url": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "address": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "agent_fallback_troubleshooting_url": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "agent_stat_refresh_interval": { + "default": 0, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": 0 + }, + "api_rate_limit": { + "default": 0, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": 0 + }, + "audit_logging": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "auto_import_templates": { + "default": ["string"], + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "autobuild_poll_interval": { + "default": 0, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": 0 + }, + "browser_only": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "cache_directory": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "derp": { + "config": { + "path": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "url": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + } + }, + "server": { + "enable": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "region_code": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "region_id": { + "default": 0, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": 0 + }, + "region_name": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "relay_url": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "stun_addresses": { + "default": ["string"], + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + } + } + }, + "experimental": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "gitauth": { + "default": [ + { + "auth_url": "string", + "client_id": "string", + "id": "string", + "no_refresh": true, + "regex": "string", + "scopes": ["string"], + "token_url": "string", + "type": "string", + "validate_url": "string" + } + ], + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": { + "auth_url": "string", + "client_id": "string", + "id": "string", + "no_refresh": true, + "regex": "string", + "scopes": ["string"], + "token_url": "string", + "type": "string", + "validate_url": "string" + } + }, + "http_address": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "in_memory_database": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "max_token_lifetime": { + "default": 0, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": 0 + }, + "metrics_cache_refresh_interval": { + "default": 0, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": 0 + }, + "oauth2": { + "github": { + "allow_everyone": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "allow_signups": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "allowed_orgs": { + "default": ["string"], + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "allowed_teams": { + "default": ["string"], + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "client_id": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "client_secret": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "enterprise_base_url": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + } + } + }, + "oidc": { + "allow_signups": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "client_id": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "client_secret": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "email_domain": { + "default": ["string"], + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "ignore_email_verified": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "issuer_url": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "scopes": { + "default": ["string"], + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + } + }, + "pg_connection_url": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "pprof": { + "address": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "enable": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + } + }, + "prometheus": { + "address": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "enable": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + } + }, + "provisioner": { + "daemon_poll_interval": { + "default": 0, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": 0 + }, + "daemon_poll_jitter": { + "default": 0, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": 0 + }, + "daemons": { + "default": 0, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": 0 + }, + "force_cancel_interval": { + "default": 0, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": 0 + } + }, + "proxy_trusted_headers": { + "default": ["string"], + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "proxy_trusted_origins": { + "default": ["string"], + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "scim_api_key": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "secure_auth_cookie": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "ssh_keygen_algorithm": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "swagger": { + "enable": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + } + }, + "telemetry": { + "enable": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "trace": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "url": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + } + }, + "tls": { + "address": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "cert_file": { + "default": ["string"], + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "client_auth": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "client_ca_file": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "client_cert_file": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "client_key_file": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "enable": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "key_file": { + "default": ["string"], + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "min_version": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "redirect_http": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + } + }, + "trace": { + "capture_logs": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "enable": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "honeycomb_api_key": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + } + }, + "update_check": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "wildcard_access_url": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + } +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ---------------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.DeploymentConfig](schemas.md#codersdkdeploymentconfig) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. ## Report CSP violations @@ -134,5 +989,3 @@ curl -X GET http://coder-server:8080/api/v2/updatecheck \ | Status | Meaning | Description | Schema | | ------ | ------------------------------------------------------- | ----------- | ---------------------------------------------------------------------- | | 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.UpdateCheckResponse](schemas.md#codersdkupdatecheckresponse) | - -undefined diff --git a/docs/api/parameters.md b/docs/api/parameters.md new file mode 100644 index 0000000000000..5b035413f09b0 --- /dev/null +++ b/docs/api/parameters.md @@ -0,0 +1,208 @@ +# Parameters + +> This page is incomplete, stay tuned. + +## Get parameters + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/parameters/{scope}/{id} \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /parameters/{scope}/{id}` + +### Parameters + +| Name | In | Type | Required | Description | +| ------- | ---- | ------------ | -------- | ----------- | +| `scope` | path | string | true | Scope | +| `id` | path | string(uuid) | true | ID | + +#### Enumerated Values + +| Parameter | Value | +| --------- | ------------ | +| `scope` | `template` | +| `scope` | `workspace` | +| `scope` | `import_job` | + +### Example responses + +> 200 Response + +```json +[ + { + "created_at": "string", + "destination_scheme": "none", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "string", + "scope": "template", + "scope_id": "5d3fe357-12dd-4f62-b004-6d1fb3b8454f", + "source_scheme": "none", + "updated_at": "string" + } +] +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ----------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | array of [codersdk.Parameter](schemas.md#codersdkparameter) | + +

Response Schema

+ +Status Code **200** + +| Name | Type | Required | Restrictions | Description | +| ---------------------- | ------ | -------- | ------------ | ------------------------------------------------- | +| `[array item]` | array | false | | [Parameter represents a set value for the scope.] | +| `» created_at` | string | false | | | +| `» destination_scheme` | string | false | | | +| `» id` | string | false | | | +| `» name` | string | false | | | +| `» scope` | string | false | | | +| `» scope_id` | string | false | | | +| `» source_scheme` | string | false | | | +| `» updated_at` | string | false | | | + +#### Enumerated Values + +| Property | Value | +| -------------------- | ---------------------- | +| `destination_scheme` | `none` | +| `destination_scheme` | `environment_variable` | +| `destination_scheme` | `provisioner_variable` | +| `scope` | `template` | +| `scope` | `workspace` | +| `scope` | `import_job` | +| `source_scheme` | `none` | +| `source_scheme` | `data` | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Create parameter + +### Code samples + +```shell +# Example request using curl +curl -X POST http://coder-server:8080/api/v2/parameters/{scope}/{id} \ + -H 'Content-Type: application/json' \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`POST /parameters/{scope}/{id}` + +> Body parameter + +```json +{ + "copy_from_parameter": "string", + "destination_scheme": "none", + "name": "string", + "source_scheme": "none", + "source_value": "string" +} +``` + +### Parameters + +| Name | In | Type | Required | Description | +| ------- | ---- | ---------------------------------------------------------------------------- | -------- | ----------------- | +| `scope` | path | string | true | Scope | +| `id` | path | string(uuid) | true | ID | +| `body` | body | [codersdk.CreateParameterRequest](schemas.md#codersdkcreateparameterrequest) | true | Parameter request | + +#### Enumerated Values + +| Parameter | Value | +| --------- | ------------ | +| `scope` | `template` | +| `scope` | `workspace` | +| `scope` | `import_job` | + +### Example responses + +> 201 Response + +```json +{ + "created_at": "string", + "destination_scheme": "none", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "string", + "scope": "template", + "scope_id": "5d3fe357-12dd-4f62-b004-6d1fb3b8454f", + "source_scheme": "none", + "updated_at": "string" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------------ | ----------- | -------------------------------------------------- | +| 201 | [Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) | Created | [codersdk.Parameter](schemas.md#codersdkparameter) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Delete parameter + +### Code samples + +```shell +# Example request using curl +curl -X DELETE http://coder-server:8080/api/v2/parameters/{scope}/{id}/{name} \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`DELETE /parameters/{scope}/{id}/{name}` + +### Parameters + +| Name | In | Type | Required | Description | +| ------- | ---- | ------------ | -------- | ----------- | +| `scope` | path | string | true | Scope | +| `id` | path | string(uuid) | true | ID | +| `name` | path | string | true | Name | + +#### Enumerated Values + +| Parameter | Value | +| --------- | ------------ | +| `scope` | `template` | +| `scope` | `workspace` | +| `scope` | `import_job` | + +### Example responses + +> 200 Response + +```json +{ + "detail": "string", + "message": "string", + "validations": [ + { + "detail": "string", + "field": "string" + } + ] +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ------------------------------------------------ | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.Response](schemas.md#codersdkresponse) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. diff --git a/docs/api/schemas.md b/docs/api/schemas.md index 601a1fc7a396a..369d9d2688cc8 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -16,6 +16,184 @@ | ------------ | ------ | -------- | ------------ | ----------- | | `csp-report` | object | false | | | +## codersdk.AuditDiff + +```json +{ + "property1": { + "new": null, + "old": null, + "secret": true + }, + "property2": { + "new": null, + "old": null, + "secret": true + } +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ---------------- | -------------------------------------------------- | -------- | ------------ | ----------- | +| `[any property]` | [codersdk.AuditDiffField](#codersdkauditdifffield) | false | | | + +## codersdk.AuditDiffField + +```json +{ + "new": null, + "old": null, + "secret": true +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| -------- | ------- | -------- | ------------ | ----------- | +| `new` | any | false | | | +| `old` | any | false | | | +| `secret` | boolean | false | | | + +## codersdk.AuditLog + +```json +{ + "action": "string", + "additional_fields": [0], + "description": "string", + "diff": { + "property1": { + "new": null, + "old": null, + "secret": true + }, + "property2": { + "new": null, + "old": null, + "secret": true + } + }, + "id": "string", + "ip": {}, + "is_deleted": true, + "organization_id": "string", + "request_id": "string", + "resource_icon": "string", + "resource_id": "string", + "resource_link": "string", + "resource_target": "string", + "resource_type": "string", + "status_code": 0, + "time": "string", + "user": { + "avatar_url": "string", + "created_at": "string", + "email": "string", + "id": "string", + "last_seen_at": "string", + "organization_ids": ["string"], + "roles": [ + { + "display_name": "string", + "name": "string" + } + ], + "status": "string", + "username": "string" + }, + "user_agent": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ------------------- | ---------------------------------------- | -------- | ------------ | -------------------------------------------- | +| `action` | string | false | | | +| `additional_fields` | array of integer | false | | | +| `description` | string | false | | | +| `diff` | [codersdk.AuditDiff](#codersdkauditdiff) | false | | | +| `id` | string | false | | | +| `ip` | [netip.Addr](#netipaddr) | false | | | +| `is_deleted` | boolean | false | | | +| `organization_id` | string | false | | | +| `request_id` | string | false | | | +| `resource_icon` | string | false | | | +| `resource_id` | string | false | | | +| `resource_link` | string | false | | | +| `resource_target` | string | false | | Resource target is the name of the resource. | +| `resource_type` | string | false | | | +| `status_code` | integer | false | | | +| `time` | string | false | | | +| `user` | [codersdk.User](#codersdkuser) | false | | | +| `user_agent` | string | false | | | + +## codersdk.AuditLogResponse + +```json +{ + "audit_logs": [ + { + "action": "string", + "additional_fields": [0], + "description": "string", + "diff": { + "property1": { + "new": null, + "old": null, + "secret": true + }, + "property2": { + "new": null, + "old": null, + "secret": true + } + }, + "id": "string", + "ip": {}, + "is_deleted": true, + "organization_id": "string", + "request_id": "string", + "resource_icon": "string", + "resource_id": "string", + "resource_link": "string", + "resource_target": "string", + "resource_type": "string", + "status_code": 0, + "time": "string", + "user": { + "avatar_url": "string", + "created_at": "string", + "email": "string", + "id": "string", + "last_seen_at": "string", + "organization_ids": ["string"], + "roles": [ + { + "display_name": "string", + "name": "string" + } + ], + "status": "string", + "username": "string" + }, + "user_agent": "string" + } + ], + "count": 0 +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ------------ | ----------------------------------------------- | -------- | ------------ | ----------- | +| `audit_logs` | array of [codersdk.AuditLog](#codersdkauditlog) | false | | | +| `count` | integer | false | | | + ## codersdk.AuthorizationCheck ```json @@ -63,35 +241,1650 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in ### Properties -| Name | Type | Required | Restrictions | Description | -| ----------------- | ------ | -------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `organization_id` | string | false | | Organization ID (optional) adds the set constraint to all resources owned by a given organization. | -| `owner_id` | string | false | | Owner ID (optional) adds the set constraint to all resources owned by a given user. | -| `resource_id` | string | false | | Resource ID (optional) reduces the set to a singular resource. This assigns a resource ID to the resource type, eg: a single workspace. The rbac library will not fetch the resource from the database, so if you are using this option, you should also set the owner ID and organization ID if possible. Be as specific as possible using all the fields relevant. | -| `resource_type` | string | false | | Resource type is the name of the resource. `./coderd/rbac/object.go` has the list of valid resource types. | +| Name | Type | Required | Restrictions | Description | +| ----------------- | ------ | -------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `organization_id` | string | false | | Organization ID (optional) adds the set constraint to all resources owned by a given organization. | +| `owner_id` | string | false | | Owner ID (optional) adds the set constraint to all resources owned by a given user. | +| `resource_id` | string | false | | Resource ID (optional) reduces the set to a singular resource. This assigns a resource ID to the resource type, eg: a single workspace. The rbac library will not fetch the resource from the database, so if you are using this option, you should also set the owner ID and organization ID if possible. Be as specific as possible using all the fields relevant. | +| `resource_type` | string | false | | Resource type is the name of the resource. `./coderd/rbac/object.go` has the list of valid resource types. | + +## codersdk.AuthorizationRequest + +```json +{ + "checks": { + "property1": { + "action": "create", + "object": { + "organization_id": "string", + "owner_id": "string", + "resource_id": "string", + "resource_type": "string" + } + }, + "property2": { + "action": "create", + "object": { + "organization_id": "string", + "owner_id": "string", + "resource_id": "string", + "resource_type": "string" + } + } + } +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ------------------ | ---------------------------------------------------------- | -------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `checks` | object | false | | Checks is a map keyed with an arbitrary string to a permission check. The key can be any string that is helpful to the caller, and allows multiple permission checks to be run in a single request. The key ensures that each permission check has the same key in the response. | +| » `[any property]` | [codersdk.AuthorizationCheck](#codersdkauthorizationcheck) | false | | It is used to check if the currently authenticated user (or the specified user) can do a given action to a given set of objects. | + +## codersdk.AuthorizationResponse + +```json +{ + "property1": true, + "property2": true +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ---------------- | ------- | -------- | ------------ | ----------- | +| `[any property]` | boolean | false | | | + +## codersdk.BuildInfoResponse + +```json +{ + "external_url": "string", + "version": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| -------------- | ------ | -------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `external_url` | string | false | | External URL references the current Coder version. For production builds, this will link directly to a release. For development builds, this will link to a commit. | +| `version` | string | false | | Version returns the semantic version of the build. | + +## codersdk.CreateParameterRequest + +```json +{ + "copy_from_parameter": "string", + "destination_scheme": "none", + "name": "string", + "source_scheme": "none", + "source_value": "string" +} +``` + +CreateParameterRequest is a structure used to create a new parameter value for a scope. + +### Properties + +| Name | Type | Required | Restrictions | Description | +| --------------------- | ------ | -------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `copy_from_parameter` | string | false | | Copy from parameter allows copying the value of another parameter. The other param must be related to the same template_id for this to succeed. No other fields are required if using this, as all fields will be copied from the other parameter. | +| `destination_scheme` | string | true | | | +| `name` | string | true | | | +| `source_scheme` | string | true | | | +| `source_value` | string | true | | | + +#### Enumerated Values + +| Property | Value | +| -------------------- | ---------------------- | +| `destination_scheme` | `none` | +| `destination_scheme` | `environment_variable` | +| `destination_scheme` | `provisioner_variable` | +| `source_scheme` | `none` | +| `source_scheme` | `data` | + +## codersdk.CreateTemplateRequest + +```json +{ + "allow_user_cancel_workspace_jobs": true, + "default_ttl_ms": 0, + "description": "string", + "display_name": "string", + "icon": "string", + "name": "string", + "parameter_values": [ + { + "copy_from_parameter": "string", + "destination_scheme": "none", + "name": "string", + "source_scheme": "none", + "source_value": "string" + } + ], + "template_version_id": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- | -------- | ------------ | ---------------------------------------------------------------------------------------------------------- | +| `allow_user_cancel_workspace_jobs` | boolean | false | | Allow users to cancel in-progress workspace jobs. \*bool as the default value is "true". | +| `default_ttl_ms` | integer | false | | Default ttl ms allows optionally specifying the default TTL for all workspaces created from this template. | +| `description` | string | false | | Description is a description of what the template contains. It must be less than 128 bytes. | +| `display_name` | string | false | | Display name is the displayed name of the template. | +| `icon` | string | false | | Icon is a relative path or external URL that specifies an icon to be displayed in the dashboard. | +| `name` | string | true | | Name is the name of the template. | +| `parameter_values` | array of [codersdk.CreateParameterRequest](#codersdkcreateparameterrequest) | false | | Parameter values is a structure used to create a new parameter value for a scope.] | +| `template_version_id` | string | true | | Template version ID is an in-progress or completed job to use as an initial version of the template. | +| 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. | + +## codersdk.CreateTestAuditLogRequest + +```json +{ + "action": "create", + "resource_id": "string", + "resource_type": "organization", + "time": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| --------------- | ------ | -------- | ------------ | ----------- | +| `action` | string | false | | | +| `resource_id` | string | false | | | +| `resource_type` | string | false | | | +| `time` | string | false | | | + +#### Enumerated Values + +| Property | Value | +| --------------- | ------------------ | +| `action` | `create` | +| `action` | `write` | +| `action` | `delete` | +| `action` | `start` | +| `action` | `stop` | +| `resource_type` | `organization` | +| `resource_type` | `template` | +| `resource_type` | `template_version` | +| `resource_type` | `user` | +| `resource_type` | `workspace` | +| `resource_type` | `workspace_build` | +| `resource_type` | `git_ssh_key` | +| `resource_type` | `api_key` | +| `resource_type` | `group` | + +## codersdk.DERP + +```json +{ + "config": { + "path": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "url": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + } + }, + "server": { + "enable": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "region_code": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "region_id": { + "default": 0, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": 0 + }, + "region_name": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "relay_url": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "stun_addresses": { + "default": ["string"], + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + } + } +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| -------- | ------------------------------------------------------ | -------- | ------------ | ----------- | +| `config` | [codersdk.DERPConfig](#codersdkderpconfig) | false | | | +| `server` | [codersdk.DERPServerConfig](#codersdkderpserverconfig) | false | | | + +## codersdk.DERPConfig + +```json +{ + "path": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "url": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + } +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ------ | ------------------------------------------------------------------------------ | -------- | ------------ | ----------- | +| `path` | [codersdk.DeploymentConfigField-string](#codersdkdeploymentconfigfield-string) | false | | | +| `url` | [codersdk.DeploymentConfigField-string](#codersdkdeploymentconfigfield-string) | false | | | + +## codersdk.DERPRegion + +```json +{ + "latency_ms": 0, + "preferred": true +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ------------ | ------- | -------- | ------------ | ----------- | +| `latency_ms` | number | false | | | +| `preferred` | boolean | false | | | + +## codersdk.DERPServerConfig + +```json +{ + "enable": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "region_code": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "region_id": { + "default": 0, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": 0 + }, + "region_name": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "relay_url": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "stun_addresses": { + "default": ["string"], + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + } +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ---------------- | ------------------------------------------------------------------------------------------ | -------- | ------------ | ----------- | +| `enable` | [codersdk.DeploymentConfigField-bool](#codersdkdeploymentconfigfield-bool) | false | | | +| `region_code` | [codersdk.DeploymentConfigField-string](#codersdkdeploymentconfigfield-string) | false | | | +| `region_id` | [codersdk.DeploymentConfigField-int](#codersdkdeploymentconfigfield-int) | false | | | +| `region_name` | [codersdk.DeploymentConfigField-string](#codersdkdeploymentconfigfield-string) | false | | | +| `relay_url` | [codersdk.DeploymentConfigField-string](#codersdkdeploymentconfigfield-string) | false | | | +| `stun_addresses` | [codersdk.DeploymentConfigField-array_string](#codersdkdeploymentconfigfield-array_string) | false | | | + +## codersdk.DeploymentConfig + +```json +{ + "access_url": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "address": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "agent_fallback_troubleshooting_url": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "agent_stat_refresh_interval": { + "default": 0, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": 0 + }, + "api_rate_limit": { + "default": 0, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": 0 + }, + "audit_logging": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "auto_import_templates": { + "default": ["string"], + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "autobuild_poll_interval": { + "default": 0, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": 0 + }, + "browser_only": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "cache_directory": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "derp": { + "config": { + "path": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "url": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + } + }, + "server": { + "enable": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "region_code": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "region_id": { + "default": 0, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": 0 + }, + "region_name": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "relay_url": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "stun_addresses": { + "default": ["string"], + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + } + } + }, + "experimental": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "gitauth": { + "default": [ + { + "auth_url": "string", + "client_id": "string", + "id": "string", + "no_refresh": true, + "regex": "string", + "scopes": ["string"], + "token_url": "string", + "type": "string", + "validate_url": "string" + } + ], + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": { + "auth_url": "string", + "client_id": "string", + "id": "string", + "no_refresh": true, + "regex": "string", + "scopes": ["string"], + "token_url": "string", + "type": "string", + "validate_url": "string" + } + }, + "http_address": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "in_memory_database": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "max_token_lifetime": { + "default": 0, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": 0 + }, + "metrics_cache_refresh_interval": { + "default": 0, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": 0 + }, + "oauth2": { + "github": { + "allow_everyone": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "allow_signups": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "allowed_orgs": { + "default": ["string"], + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "allowed_teams": { + "default": ["string"], + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "client_id": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "client_secret": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "enterprise_base_url": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + } + } + }, + "oidc": { + "allow_signups": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "client_id": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "client_secret": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "email_domain": { + "default": ["string"], + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "ignore_email_verified": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "issuer_url": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "scopes": { + "default": ["string"], + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + } + }, + "pg_connection_url": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "pprof": { + "address": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "enable": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + } + }, + "prometheus": { + "address": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "enable": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + } + }, + "provisioner": { + "daemon_poll_interval": { + "default": 0, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": 0 + }, + "daemon_poll_jitter": { + "default": 0, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": 0 + }, + "daemons": { + "default": 0, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": 0 + }, + "force_cancel_interval": { + "default": 0, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": 0 + } + }, + "proxy_trusted_headers": { + "default": ["string"], + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "proxy_trusted_origins": { + "default": ["string"], + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "scim_api_key": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "secure_auth_cookie": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "ssh_keygen_algorithm": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "swagger": { + "enable": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + } + }, + "telemetry": { + "enable": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "trace": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "url": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + } + }, + "tls": { + "address": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "cert_file": { + "default": ["string"], + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "client_auth": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "client_ca_file": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "client_cert_file": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "client_key_file": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "enable": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "key_file": { + "default": ["string"], + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "min_version": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "redirect_http": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + } + }, + "trace": { + "capture_logs": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "enable": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "honeycomb_api_key": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + } + }, + "update_check": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "wildcard_access_url": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + } +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------- | -------- | ------------ | ----------- | +| `access_url` | [codersdk.DeploymentConfigField-string](#codersdkdeploymentconfigfield-string) | false | | | +| `address` | [codersdk.DeploymentConfigField-string](#codersdkdeploymentconfigfield-string) | false | | | +| `agent_fallback_troubleshooting_url` | [codersdk.DeploymentConfigField-string](#codersdkdeploymentconfigfield-string) | false | | | +| `agent_stat_refresh_interval` | [codersdk.DeploymentConfigField-time_Duration](#codersdkdeploymentconfigfield-time_duration) | false | | | +| `api_rate_limit` | [codersdk.DeploymentConfigField-int](#codersdkdeploymentconfigfield-int) | false | | | +| `audit_logging` | [codersdk.DeploymentConfigField-bool](#codersdkdeploymentconfigfield-bool) | false | | | +| `auto_import_templates` | [codersdk.DeploymentConfigField-array_string](#codersdkdeploymentconfigfield-array_string) | false | | | +| `autobuild_poll_interval` | [codersdk.DeploymentConfigField-time_Duration](#codersdkdeploymentconfigfield-time_duration) | false | | | +| `browser_only` | [codersdk.DeploymentConfigField-bool](#codersdkdeploymentconfigfield-bool) | false | | | +| `cache_directory` | [codersdk.DeploymentConfigField-string](#codersdkdeploymentconfigfield-string) | false | | | +| `derp` | [codersdk.DERP](#codersdkderp) | false | | | +| `experimental` | [codersdk.DeploymentConfigField-bool](#codersdkdeploymentconfigfield-bool) | false | | | +| `gitauth` | [codersdk.DeploymentConfigField-array_codersdk_GitAuthConfig](#codersdkdeploymentconfigfield-array_codersdk_gitauthconfig) | false | | | +| `http_address` | [codersdk.DeploymentConfigField-string](#codersdkdeploymentconfigfield-string) | false | | | +| `in_memory_database` | [codersdk.DeploymentConfigField-bool](#codersdkdeploymentconfigfield-bool) | false | | | +| `max_token_lifetime` | [codersdk.DeploymentConfigField-time_Duration](#codersdkdeploymentconfigfield-time_duration) | false | | | +| `metrics_cache_refresh_interval` | [codersdk.DeploymentConfigField-time_Duration](#codersdkdeploymentconfigfield-time_duration) | false | | | +| `oauth2` | [codersdk.OAuth2Config](#codersdkoauth2config) | false | | | +| `oidc` | [codersdk.OIDCConfig](#codersdkoidcconfig) | false | | | +| `pg_connection_url` | [codersdk.DeploymentConfigField-string](#codersdkdeploymentconfigfield-string) | false | | | +| `pprof` | [codersdk.PprofConfig](#codersdkpprofconfig) | false | | | +| `prometheus` | [codersdk.PrometheusConfig](#codersdkprometheusconfig) | false | | | +| `provisioner` | [codersdk.ProvisionerConfig](#codersdkprovisionerconfig) | false | | | +| `proxy_trusted_headers` | [codersdk.DeploymentConfigField-array_string](#codersdkdeploymentconfigfield-array_string) | false | | | +| `proxy_trusted_origins` | [codersdk.DeploymentConfigField-array_string](#codersdkdeploymentconfigfield-array_string) | false | | | +| `scim_api_key` | [codersdk.DeploymentConfigField-string](#codersdkdeploymentconfigfield-string) | false | | | +| `secure_auth_cookie` | [codersdk.DeploymentConfigField-bool](#codersdkdeploymentconfigfield-bool) | false | | | +| `ssh_keygen_algorithm` | [codersdk.DeploymentConfigField-string](#codersdkdeploymentconfigfield-string) | false | | | +| `swagger` | [codersdk.SwaggerConfig](#codersdkswaggerconfig) | false | | | +| `telemetry` | [codersdk.TelemetryConfig](#codersdktelemetryconfig) | false | | | +| `tls` | [codersdk.TLSConfig](#codersdktlsconfig) | false | | | +| `trace` | [codersdk.TraceConfig](#codersdktraceconfig) | false | | | +| `update_check` | [codersdk.DeploymentConfigField-bool](#codersdkdeploymentconfigfield-bool) | false | | | +| `wildcard_access_url` | [codersdk.DeploymentConfigField-string](#codersdkdeploymentconfigfield-string) | false | | | + +## codersdk.DeploymentConfigField-array_codersdk_GitAuthConfig + +```json +{ + "default": [ + { + "auth_url": "string", + "client_id": "string", + "id": "string", + "no_refresh": true, + "regex": "string", + "scopes": ["string"], + "token_url": "string", + "type": "string", + "validate_url": "string" + } + ], + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": { + "auth_url": "string", + "client_id": "string", + "id": "string", + "no_refresh": true, + "regex": "string", + "scopes": ["string"], + "token_url": "string", + "type": "string", + "validate_url": "string" + } +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ------------ | --------------------------------------------------------- | -------- | ------------ | ----------- | +| `default` | array of [codersdk.GitAuthConfig](#codersdkgitauthconfig) | false | | | +| `enterprise` | boolean | false | | | +| `flag` | string | false | | | +| `hidden` | boolean | false | | | +| `name` | string | false | | | +| `secret` | boolean | false | | | +| `shorthand` | string | false | | | +| `usage` | string | false | | | +| `value` | [codersdk.GitAuthConfig](#codersdkgitauthconfig) | false | | | + +## codersdk.DeploymentConfigField-array_string + +```json +{ + "default": ["string"], + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ------------ | --------------- | -------- | ------------ | ----------- | +| `default` | array of string | false | | | +| `enterprise` | boolean | false | | | +| `flag` | string | false | | | +| `hidden` | boolean | false | | | +| `name` | string | false | | | +| `secret` | boolean | false | | | +| `shorthand` | string | false | | | +| `usage` | string | false | | | +| `value` | string | false | | | + +## codersdk.DeploymentConfigField-bool + +```json +{ + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ------------ | ------- | -------- | ------------ | ----------- | +| `default` | boolean | false | | | +| `enterprise` | boolean | false | | | +| `flag` | string | false | | | +| `hidden` | boolean | false | | | +| `name` | string | false | | | +| `secret` | boolean | false | | | +| `shorthand` | string | false | | | +| `usage` | string | false | | | +| `value` | boolean | false | | | + +## codersdk.DeploymentConfigField-int + +```json +{ + "default": 0, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": 0 +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ------------ | ------- | -------- | ------------ | ----------- | +| `default` | integer | false | | | +| `enterprise` | boolean | false | | | +| `flag` | string | false | | | +| `hidden` | boolean | false | | | +| `name` | string | false | | | +| `secret` | boolean | false | | | +| `shorthand` | string | false | | | +| `usage` | string | false | | | +| `value` | integer | false | | | + +## codersdk.DeploymentConfigField-string + +```json +{ + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ------------ | ------- | -------- | ------------ | ----------- | +| `default` | string | false | | | +| `enterprise` | boolean | false | | | +| `flag` | string | false | | | +| `hidden` | boolean | false | | | +| `name` | string | false | | | +| `secret` | boolean | false | | | +| `shorthand` | string | false | | | +| `usage` | string | false | | | +| `value` | string | false | | | + +## codersdk.DeploymentConfigField-time_Duration + +```json +{ + "default": 0, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": 0 +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ------------ | ------- | -------- | ------------ | ----------- | +| `default` | integer | false | | | +| `enterprise` | boolean | false | | | +| `flag` | string | false | | | +| `hidden` | boolean | false | | | +| `name` | string | false | | | +| `secret` | boolean | false | | | +| `shorthand` | string | false | | | +| `usage` | string | false | | | +| `value` | integer | false | | | + +## codersdk.GetAppHostResponse + +```json +{ + "host": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ------ | ------ | -------- | ------------ | ------------------------------------------------------------- | +| `host` | string | false | | Host is the externally accessible URL for the Coder instance. | + +## codersdk.GitAuthConfig + +```json +{ + "auth_url": "string", + "client_id": "string", + "id": "string", + "no_refresh": true, + "regex": "string", + "scopes": ["string"], + "token_url": "string", + "type": "string", + "validate_url": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| -------------- | --------------- | -------- | ------------ | ----------- | +| `auth_url` | string | false | | | +| `client_id` | string | false | | | +| `id` | string | false | | | +| `no_refresh` | boolean | false | | | +| `regex` | string | false | | | +| `scopes` | array of string | false | | | +| `token_url` | string | false | | | +| `type` | string | false | | | +| `validate_url` | string | false | | | + +## codersdk.Healthcheck + +```json +{ + "interval": 0, + "threshold": 0, + "url": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ----------- | ------- | -------- | ------------ | ------------------------------------------------------------------------------------------------ | +| `interval` | integer | false | | Interval specifies the seconds between each health check. | +| `threshold` | integer | false | | Threshold specifies the number of consecutive failed health checks before returning "unhealthy". | +| `url` | string | false | | URL specifies the endpoint to check for the app health. | -## codersdk.AuthorizationRequest +## codersdk.OAuth2Config ```json { - "checks": { - "property1": { - "action": "create", - "object": { - "organization_id": "string", - "owner_id": "string", - "resource_id": "string", - "resource_type": "string" - } + "github": { + "allow_everyone": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true }, - "property2": { - "action": "create", - "object": { - "organization_id": "string", - "owner_id": "string", - "resource_id": "string", - "resource_type": "string" - } + "allow_signups": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "allowed_orgs": { + "default": ["string"], + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "allowed_teams": { + "default": ["string"], + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "client_id": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "client_secret": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "enterprise_base_url": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" } } } @@ -99,158 +1892,376 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in ### Properties -| Name | Type | Required | Restrictions | Description | -| ------------------ | ---------------------------------------------------------- | -------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `checks` | object | false | | Checks is a map keyed with an arbitrary string to a permission check. The key can be any string that is helpful to the caller, and allows multiple permission checks to be run in a single request. The key ensures that each permission check has the same key in the response. | -| » `[any property]` | [codersdk.AuthorizationCheck](#codersdkauthorizationcheck) | false | | It is used to check if the currently authenticated user (or the specified user) can do a given action to a given set of objects. | +| Name | Type | Required | Restrictions | Description | +| -------- | ---------------------------------------------------------- | -------- | ------------ | ----------- | +| `github` | [codersdk.OAuth2GithubConfig](#codersdkoauth2githubconfig) | false | | | -## codersdk.AuthorizationResponse +## codersdk.OAuth2GithubConfig ```json { - "property1": true, - "property2": true + "allow_everyone": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "allow_signups": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "allowed_orgs": { + "default": ["string"], + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "allowed_teams": { + "default": ["string"], + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "client_id": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "client_secret": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "enterprise_base_url": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + } } ``` ### Properties -| Name | Type | Required | Restrictions | Description | -| ---------------- | ------- | -------- | ------------ | ----------- | -| `[any property]` | boolean | false | | | +| Name | Type | Required | Restrictions | Description | +| --------------------- | ------------------------------------------------------------------------------------------ | -------- | ------------ | ----------- | +| `allow_everyone` | [codersdk.DeploymentConfigField-bool](#codersdkdeploymentconfigfield-bool) | false | | | +| `allow_signups` | [codersdk.DeploymentConfigField-bool](#codersdkdeploymentconfigfield-bool) | false | | | +| `allowed_orgs` | [codersdk.DeploymentConfigField-array_string](#codersdkdeploymentconfigfield-array_string) | false | | | +| `allowed_teams` | [codersdk.DeploymentConfigField-array_string](#codersdkdeploymentconfigfield-array_string) | false | | | +| `client_id` | [codersdk.DeploymentConfigField-string](#codersdkdeploymentconfigfield-string) | false | | | +| `client_secret` | [codersdk.DeploymentConfigField-string](#codersdkdeploymentconfigfield-string) | false | | | +| `enterprise_base_url` | [codersdk.DeploymentConfigField-string](#codersdkdeploymentconfigfield-string) | false | | | -## codersdk.BuildInfoResponse +## codersdk.OIDCConfig ```json { - "external_url": "string", - "version": "string" + "allow_signups": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "client_id": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "client_secret": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "email_domain": { + "default": ["string"], + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "ignore_email_verified": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "issuer_url": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "scopes": { + "default": ["string"], + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + } } ``` ### Properties -| Name | Type | Required | Restrictions | Description | -| -------------- | ------ | -------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `external_url` | string | false | | External URL references the current Coder version. For production builds, this will link directly to a release. For development builds, this will link to a commit. | -| `version` | string | false | | Version returns the semantic version of the build. | +| Name | Type | Required | Restrictions | Description | +| ----------------------- | ------------------------------------------------------------------------------------------ | -------- | ------------ | ----------- | +| `allow_signups` | [codersdk.DeploymentConfigField-bool](#codersdkdeploymentconfigfield-bool) | false | | | +| `client_id` | [codersdk.DeploymentConfigField-string](#codersdkdeploymentconfigfield-string) | false | | | +| `client_secret` | [codersdk.DeploymentConfigField-string](#codersdkdeploymentconfigfield-string) | false | | | +| `email_domain` | [codersdk.DeploymentConfigField-array_string](#codersdkdeploymentconfigfield-array_string) | false | | | +| `ignore_email_verified` | [codersdk.DeploymentConfigField-bool](#codersdkdeploymentconfigfield-bool) | false | | | +| `issuer_url` | [codersdk.DeploymentConfigField-string](#codersdkdeploymentconfigfield-string) | false | | | +| `scopes` | [codersdk.DeploymentConfigField-array_string](#codersdkdeploymentconfigfield-array_string) | false | | | -## codersdk.CreateParameterRequest +## codersdk.Parameter ```json { - "copy_from_parameter": "string", - "destination_scheme": "environment_variable", + "created_at": "string", + "destination_scheme": "none", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "name": "string", - "source_scheme": "data", - "source_value": "string" + "scope": "template", + "scope_id": "5d3fe357-12dd-4f62-b004-6d1fb3b8454f", + "source_scheme": "none", + "updated_at": "string" } ``` -CreateParameterRequest is a structure used to create a new parameter value for a scope. +Parameter represents a set value for the scope. ### Properties -| Name | Type | Required | Restrictions | Description | -| --------------------- | ------ | -------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `copy_from_parameter` | string | false | | Copy from parameter allows copying the value of another parameter. The other param must be related to the same template_id for this to succeed. No other fields are required if using this, as all fields will be copied from the other parameter. | -| `destination_scheme` | string | true | | | -| `name` | string | true | | | -| `source_scheme` | string | true | | | -| `source_value` | string | true | | | +| Name | Type | Required | Restrictions | Description | +| -------------------- | ------ | -------- | ------------ | ----------- | +| `created_at` | string | false | | | +| `destination_scheme` | string | false | | | +| `id` | string | false | | | +| `name` | string | false | | | +| `scope` | string | false | | | +| `scope_id` | string | false | | | +| `source_scheme` | string | false | | | +| `updated_at` | string | false | | | #### Enumerated Values | Property | Value | | -------------------- | ---------------------- | +| `destination_scheme` | `none` | | `destination_scheme` | `environment_variable` | | `destination_scheme` | `provisioner_variable` | +| `scope` | `template` | +| `scope` | `workspace` | +| `scope` | `import_job` | +| `source_scheme` | `none` | | `source_scheme` | `data` | -## codersdk.CreateTemplateRequest - -```json -{ - "allow_user_cancel_workspace_jobs": true, - "default_ttl_ms": 0, - "description": "string", - "display_name": "string", - "icon": "string", - "name": "string", - "parameter_values": [ - { - "copy_from_parameter": "string", - "destination_scheme": "environment_variable", - "name": "string", - "source_scheme": "data", - "source_value": "string" - } - ], - "template_version_id": "string" -} -``` - -### Properties - -| Name | Type | Required | Restrictions | Description | -| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- | -------- | ------------ | ---------------------------------------------------------------------------------------------------------- | -| `allow_user_cancel_workspace_jobs` | boolean | false | | Allow users to cancel in-progress workspace jobs. \*bool as the default value is "true". | -| `default_ttl_ms` | integer | false | | Default ttl ms allows optionally specifying the default TTL for all workspaces created from this template. | -| `description` | string | false | | Description is a description of what the template contains. It must be less than 128 bytes. | -| `display_name` | string | false | | Display name is the displayed name of the template. | -| `icon` | string | false | | Icon is a relative path or external URL that specifies an icon to be displayed in the dashboard. | -| `name` | string | true | | Name is the name of the template. | -| `parameter_values` | array of [codersdk.CreateParameterRequest](#codersdkcreateparameterrequest) | false | | Parameter values is a structure used to create a new parameter value for a scope.] | -| `template_version_id` | string | true | | Template version ID is an in-progress or completed job to use as an initial version of the template. | -| 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. | - -## codersdk.DERPRegion +## codersdk.PprofConfig ```json { - "latency_ms": 0, - "preferred": true + "address": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "enable": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + } } ``` ### Properties -| Name | Type | Required | Restrictions | Description | -| ------------ | ------- | -------- | ------------ | ----------- | -| `latency_ms` | number | false | | | -| `preferred` | boolean | false | | | +| Name | Type | Required | Restrictions | Description | +| --------- | ------------------------------------------------------------------------------ | -------- | ------------ | ----------- | +| `address` | [codersdk.DeploymentConfigField-string](#codersdkdeploymentconfigfield-string) | false | | | +| `enable` | [codersdk.DeploymentConfigField-bool](#codersdkdeploymentconfigfield-bool) | false | | | -## codersdk.GetAppHostResponse +## codersdk.PrometheusConfig ```json { - "host": "string" + "address": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "enable": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + } } ``` ### Properties -| Name | Type | Required | Restrictions | Description | -| ------ | ------ | -------- | ------------ | ------------------------------------------------------------- | -| `host` | string | false | | Host is the externally accessible URL for the Coder instance. | +| Name | Type | Required | Restrictions | Description | +| --------- | ------------------------------------------------------------------------------ | -------- | ------------ | ----------- | +| `address` | [codersdk.DeploymentConfigField-string](#codersdkdeploymentconfigfield-string) | false | | | +| `enable` | [codersdk.DeploymentConfigField-bool](#codersdkdeploymentconfigfield-bool) | false | | | -## codersdk.Healthcheck +## codersdk.ProvisionerConfig ```json { - "interval": 0, - "threshold": 0, - "url": "string" + "daemon_poll_interval": { + "default": 0, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": 0 + }, + "daemon_poll_jitter": { + "default": 0, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": 0 + }, + "daemons": { + "default": 0, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": 0 + }, + "force_cancel_interval": { + "default": 0, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": 0 + } } ``` ### Properties -| Name | Type | Required | Restrictions | Description | -| ----------- | ------- | -------- | ------------ | ------------------------------------------------------------------------------------------------ | -| `interval` | integer | false | | Interval specifies the seconds between each health check. | -| `threshold` | integer | false | | Threshold specifies the number of consecutive failed health checks before returning "unhealthy". | -| `url` | string | false | | URL specifies the endpoint to check for the app health. | +| Name | Type | Required | Restrictions | Description | +| ----------------------- | -------------------------------------------------------------------------------------------- | -------- | ------------ | ----------- | +| `daemon_poll_interval` | [codersdk.DeploymentConfigField-time_Duration](#codersdkdeploymentconfigfield-time_duration) | false | | | +| `daemon_poll_jitter` | [codersdk.DeploymentConfigField-time_Duration](#codersdkdeploymentconfigfield-time_duration) | false | | | +| `daemons` | [codersdk.DeploymentConfigField-int](#codersdkdeploymentconfigfield-int) | false | | | +| `force_cancel_interval` | [codersdk.DeploymentConfigField-time_Duration](#codersdkdeploymentconfigfield-time_duration) | false | | | ## codersdk.ProvisionerJob @@ -325,6 +2336,226 @@ CreateParameterRequest is a structure used to create a new parameter value for a | `message` | string | false | | Message is an actionable message that depicts actions the request took. These messages should be fully formed sentences with proper punctuation. Examples: - "A user has been created." - "Failed to create a user." | | `validations` | array of [codersdk.ValidationError](#codersdkvalidationerror) | false | | Validations are form field-specific friendly error messages. They will be shown on a form field in the UI. These can also be used to add additional context if there is a set of errors in the primary 'Message'. | +## codersdk.Role + +```json +{ + "display_name": "string", + "name": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| -------------- | ------ | -------- | ------------ | ----------- | +| `display_name` | string | false | | | +| `name` | string | false | | | + +## codersdk.SwaggerConfig + +```json +{ + "enable": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + } +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| -------- | -------------------------------------------------------------------------- | -------- | ------------ | ----------- | +| `enable` | [codersdk.DeploymentConfigField-bool](#codersdkdeploymentconfigfield-bool) | false | | | + +## codersdk.TLSConfig + +```json +{ + "address": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "cert_file": { + "default": ["string"], + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "client_auth": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "client_ca_file": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "client_cert_file": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "client_key_file": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "enable": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "key_file": { + "default": ["string"], + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "min_version": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + }, + "redirect_http": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + } +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ------------------ | ------------------------------------------------------------------------------------------ | -------- | ------------ | ----------- | +| `address` | [codersdk.DeploymentConfigField-string](#codersdkdeploymentconfigfield-string) | false | | | +| `cert_file` | [codersdk.DeploymentConfigField-array_string](#codersdkdeploymentconfigfield-array_string) | false | | | +| `client_auth` | [codersdk.DeploymentConfigField-string](#codersdkdeploymentconfigfield-string) | false | | | +| `client_ca_file` | [codersdk.DeploymentConfigField-string](#codersdkdeploymentconfigfield-string) | false | | | +| `client_cert_file` | [codersdk.DeploymentConfigField-string](#codersdkdeploymentconfigfield-string) | false | | | +| `client_key_file` | [codersdk.DeploymentConfigField-string](#codersdkdeploymentconfigfield-string) | false | | | +| `enable` | [codersdk.DeploymentConfigField-bool](#codersdkdeploymentconfigfield-bool) | false | | | +| `key_file` | [codersdk.DeploymentConfigField-array_string](#codersdkdeploymentconfigfield-array_string) | false | | | +| `min_version` | [codersdk.DeploymentConfigField-string](#codersdkdeploymentconfigfield-string) | false | | | +| `redirect_http` | [codersdk.DeploymentConfigField-bool](#codersdkdeploymentconfigfield-bool) | false | | | + +## codersdk.TelemetryConfig + +```json +{ + "enable": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "trace": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "url": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + } +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| -------- | ------------------------------------------------------------------------------ | -------- | ------------ | ----------- | +| `enable` | [codersdk.DeploymentConfigField-bool](#codersdkdeploymentconfigfield-bool) | false | | | +| `trace` | [codersdk.DeploymentConfigField-bool](#codersdkdeploymentconfigfield-bool) | false | | | +| `url` | [codersdk.DeploymentConfigField-string](#codersdkdeploymentconfigfield-string) | false | | | + ## codersdk.Template ```json @@ -401,6 +2632,54 @@ CreateParameterRequest is a structure used to create a new parameter value for a | ---------------- | ---------------------------------------------------- | -------- | ------------ | ----------- | | `[any property]` | [codersdk.TransitionStats](#codersdktransitionstats) | false | | | +## codersdk.TraceConfig + +```json +{ + "capture_logs": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "enable": { + "default": true, + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": true + }, + "honeycomb_api_key": { + "default": "string", + "enterprise": true, + "flag": "string", + "hidden": true, + "name": "string", + "secret": true, + "shorthand": "string", + "usage": "string", + "value": "string" + } +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ------------------- | ------------------------------------------------------------------------------ | -------- | ------------ | ----------- | +| `capture_logs` | [codersdk.DeploymentConfigField-bool](#codersdkdeploymentconfigfield-bool) | false | | | +| `enable` | [codersdk.DeploymentConfigField-bool](#codersdkdeploymentconfigfield-bool) | false | | | +| `honeycomb_api_key` | [codersdk.DeploymentConfigField-string](#codersdkdeploymentconfigfield-string) | false | | | + ## codersdk.TransitionStats ```json @@ -477,6 +2756,55 @@ CreateParameterRequest is a structure used to create a new parameter value for a | -------- | ------- | -------- | ------------ | ----------- | | `ttl_ms` | integer | false | | | +## codersdk.UploadResponse + +```json +{ + "hash": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ------ | ------ | -------- | ------------ | ----------- | +| `hash` | string | false | | | + +## codersdk.User + +```json +{ + "avatar_url": "string", + "created_at": "string", + "email": "string", + "id": "string", + "last_seen_at": "string", + "organization_ids": ["string"], + "roles": [ + { + "display_name": "string", + "name": "string" + } + ], + "status": "string", + "username": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ------------------ | --------------------------------------- | -------- | ------------ | ----------- | +| `avatar_url` | string | false | | | +| `created_at` | string | true | | | +| `email` | string | true | | | +| `id` | string | true | | | +| `last_seen_at` | string | false | | | +| `organization_ids` | array of string | false | | | +| `roles` | array of [codersdk.Role](#codersdkrole) | false | | | +| `status` | string | false | | | +| `username` | string | true | | | + ## codersdk.ValidationError ```json @@ -505,10 +2833,7 @@ CreateParameterRequest is a structure used to create a new parameter value for a "build_number": 0, "created_at": "2019-08-24T14:15:22Z", "daily_cost": 0, - "deadline": { - "time": "string", - "valid": true - }, + "deadline": "2019-08-24T14:15:22Z", "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3", "initiator_name": "string", @@ -776,10 +3101,7 @@ CreateParameterRequest is a structure used to create a new parameter value for a "build_number": 0, "created_at": "2019-08-24T14:15:22Z", "daily_cost": 0, - "deadline": { - "time": "string", - "valid": true - }, + "deadline": "2019-08-24T14:15:22Z", "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3", "initiator_name": "string", @@ -892,7 +3214,7 @@ CreateParameterRequest is a structure used to create a new parameter value for a | `build_number` | integer | false | | | | `created_at` | string | false | | | | `daily_cost` | integer | false | | | -| `deadline` | string(time) or `null` | false | | | +| `deadline` | string | false | | | | `id` | string | false | | | | `initiator_id` | string | false | | | | `initiator_name` | string | false | | | @@ -1061,10 +3383,7 @@ CreateParameterRequest is a structure used to create a new parameter value for a "build_number": 0, "created_at": "2019-08-24T14:15:22Z", "daily_cost": 0, - "deadline": { - "time": "string", - "valid": true - }, + "deadline": "2019-08-24T14:15:22Z", "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3", "initiator_name": "string", @@ -1186,3 +3505,13 @@ CreateParameterRequest is a structure used to create a new parameter value for a | ------------ | ------------------------------------------------- | -------- | ------------ | ----------- | | `count` | integer | false | | | | `workspaces` | array of [codersdk.Workspace](#codersdkworkspace) | false | | | + +## netip.Addr + +```json +{} +``` + +### Properties + +_None_ diff --git a/docs/api/templates.md b/docs/api/templates.md index 23a7260494db6..0cde6eaef5926 100644 --- a/docs/api/templates.md +++ b/docs/api/templates.md @@ -29,9 +29,9 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization-id}/tem "parameter_values": [ { "copy_from_parameter": "string", - "destination_scheme": "environment_variable", + "destination_scheme": "none", "name": "string", - "source_scheme": "data", + "source_scheme": "none", "source_value": "string" } ], @@ -244,7 +244,7 @@ curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/templat To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. -## Update template metadata by ID +## Get template metadata by ID ### Code samples @@ -349,3 +349,65 @@ curl -X DELETE http://coder-server:8080/api/v2/templates/{id} \ | 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.Response](schemas.md#codersdkresponse) | To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Update template metadata by ID + +### Code samples + +```shell +# Example request using curl +curl -X PATCH http://coder-server:8080/api/v2/templates/{id} \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`PATCH /templates/{id}` + +### Parameters + +| Name | In | Type | Required | Description | +| ---- | ---- | ------------ | -------- | ----------- | +| `id` | path | string(uuid) | true | Template ID | + +### Example responses + +> 200 Response + +```json +{ + "active_user_count": 0, + "active_version_id": "string", + "allow_user_cancel_workspace_jobs": true, + "build_time_stats": { + "property1": { + "p50": 123, + "p95": 146 + }, + "property2": { + "p50": 123, + "p95": 146 + } + }, + "created_at": "2019-08-24T14:15:22Z", + "created_by_id": "9377d689-01fb-4abf-8450-3368d2c1924f", + "created_by_name": "string", + "default_ttl_ms": 0, + "description": "string", + "display_name": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "provisioner": "string", + "updated_at": "2019-08-24T14:15:22Z", + "workspace_owner_count": 0 +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ------------------------------------------------ | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.Template](schemas.md#codersdktemplate) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. diff --git a/docs/api/workspaces.md b/docs/api/workspaces.md index fcbfcda60d60e..4739d86a90715 100644 --- a/docs/api/workspaces.md +++ b/docs/api/workspaces.md @@ -36,10 +36,7 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/member "build_number": 0, "created_at": "2019-08-24T14:15:22Z", "daily_cost": 0, - "deadline": { - "time": "string", - "valid": true - }, + "deadline": "2019-08-24T14:15:22Z", "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3", "initiator_name": "string", @@ -200,10 +197,7 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/workspace/{workspacenam "build_number": 0, "created_at": "2019-08-24T14:15:22Z", "daily_cost": 0, - "deadline": { - "time": "string", - "valid": true - }, + "deadline": "2019-08-24T14:15:22Z", "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3", "initiator_name": "string", @@ -387,10 +381,7 @@ curl -X GET http://coder-server:8080/api/v2/workspaces \ "build_number": 0, "created_at": "2019-08-24T14:15:22Z", "daily_cost": 0, - "deadline": { - "time": "string", - "valid": true - }, + "deadline": "2019-08-24T14:15:22Z", "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3", "initiator_name": "string", @@ -548,10 +539,7 @@ curl -X GET http://coder-server:8080/api/v2/workspaces/{id} \ "build_number": 0, "created_at": "2019-08-24T14:15:22Z", "daily_cost": 0, - "deadline": { - "time": "string", - "valid": true - }, + "deadline": "2019-08-24T14:15:22Z", "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3", "initiator_name": "string", diff --git a/docs/manifest.json b/docs/manifest.json index 5e3e78386ea03..5e20465ae272e 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -337,10 +337,18 @@ "title": "Applications", "path": "./api/applications.md" }, + { + "title": "Audit", + "path": "./api/audit.md" + }, { "title": "Authorization", "path": "./api/authorization.md" }, + { + "title": "Files", + "path": "./api/files.md" + }, { "title": "Templates", "path": "./api/templates.md" @@ -349,6 +357,10 @@ "title": "Workspaces", "path": "./api/workspaces.md" }, + { + "title": "Parameters", + "path": "./api/parameters.md" + }, { "title": "Schemas", "path": "./api/schemas.md" diff --git a/scripts/apidocgen/markdown-template/code_shell.dot b/scripts/apidocgen/markdown-template/code_shell.dot index 041b3d92a0344..7300ae4ab29aa 100644 --- a/scripts/apidocgen/markdown-template/code_shell.dot +++ b/scripts/apidocgen/markdown-template/code_shell.dot @@ -1,4 +1,8 @@ # Example request using curl curl -X {{=data.methodUpper}} http://coder-server:8080{{=data.url}}{{=data.requiredQueryString}}{{?data.allHeaders.length}} \{{?}} -{{~data.allHeaders :p:index}} -H '{{=p.name}}: {{=p.exampleValues.object}}'{{?index < data.allHeaders.length-1}} \ +{{~data.allHeaders :p:index}}{{ + if (p.name == "Content-Type" && p.exampleValues.object == "application/x-www-form-urlencoded") { + continue; + } +}} -H '{{=p.name}}: {{=p.exampleValues.object}}'{{?index < data.allHeaders.length-1}} \ {{?}}{{~}} diff --git a/scripts/apidocgen/markdown-template/main.dot b/scripts/apidocgen/markdown-template/main.dot index d040a95fa4490..59236d94a9fbd 100644 --- a/scripts/apidocgen/markdown-template/main.dot +++ b/scripts/apidocgen/markdown-template/main.dot @@ -5,9 +5,6 @@ } const pRef = p.$ref.replace("#/components/schemas/",""); - if (pRef == "codersdk.NullTime") { - return "string(time) or `null`"; - } return "[" + pRef + "](#" + pRef.replace(".","").toLowerCase() + ")"; } diff --git a/scripts/apidocgen/markdown-template/operation.dot b/scripts/apidocgen/markdown-template/operation.dot index f0363bcbabf45..e5d833172facd 100644 --- a/scripts/apidocgen/markdown-template/operation.dot +++ b/scripts/apidocgen/markdown-template/operation.dot @@ -48,7 +48,5 @@ {{ data.security = data.operation.security ? data.operation.security : data.api.security; }} {{? data.security && data.security.length }} {{#def.authentication}} -{{??}} -{{#def.authentication_none}} {{?}} {{= data.tags.endSection }} From fbe1d7088eb7fe90a56b0318448d934859294be7 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Mon, 2 Jan 2023 12:12:53 +0100 Subject: [PATCH 02/36] Swagger comments in workspacebuilds.go --- coderd/apidoc/docs.go | 217 ++++++++++++++ coderd/apidoc/swagger.json | 197 +++++++++++++ coderd/workspacebuilds.go | 43 +++ docs/api/schemas.md | 24 ++ docs/api/workspaces.md | 565 +++++++++++++++++++++++++++++++++++++ 5 files changed, 1046 insertions(+) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 5ff12f9fb8f8f..8249ee27fa45d 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -875,6 +875,200 @@ const docTemplate = `{ } } }, + "/workspacebuilds/{workspacebuild}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Workspaces" + ], + "summary": "Get workspace build", + "operationId": "get-workspace-build", + "parameters": [ + { + "type": "string", + "description": "Workspace build ID", + "name": "workspacebuild", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceBuild" + } + } + } + } + }, + "/workspacebuilds/{workspacebuild}/cancel": { + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Workspaces" + ], + "summary": "Cancel workspace build", + "operationId": "cancel-workspace-build", + "parameters": [ + { + "type": "string", + "description": "Workspace build ID", + "name": "workspacebuild", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, + "/workspacebuilds/{workspacebuild}/logs": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Workspaces" + ], + "summary": "Get workspace build logs", + "operationId": "get-workspace-build-logs", + "parameters": [ + { + "type": "string", + "description": "Workspace build ID", + "name": "workspacebuild", + "in": "path", + "required": true + }, + { + "type": "integer", + "description": "Before Unix timestamp", + "name": "before", + "in": "query" + }, + { + "type": "integer", + "description": "After Unix timestamp", + "name": "after", + "in": "query" + }, + { + "type": "boolean", + "description": "Follow log stream", + "name": "follow", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.ProvisionerJobLog" + } + } + } + } + } + }, + "/workspacebuilds/{workspacebuild}/resources": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Workspaces" + ], + "summary": "Get workspace resources for workspace build", + "operationId": "get-workspace-resources-for-workspace-build", + "parameters": [ + { + "type": "string", + "description": "Workspace build ID", + "name": "workspacebuild", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceResource" + } + } + } + } + } + }, + "/workspacebuilds/{workspacebuild}/state": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Workspaces" + ], + "summary": "Get provisioner state for workspace build", + "operationId": "get-provisioner-state-for-workspace-build", + "parameters": [ + { + "type": "string", + "description": "Workspace build ID", + "name": "workspacebuild", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceBuild" + } + } + } + } + }, "/workspaces": { "get": { "security": [ @@ -2101,6 +2295,29 @@ const docTemplate = `{ } } }, + "codersdk.ProvisionerJobLog": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "log_level": { + "type": "string" + }, + "log_source": { + "type": "string" + }, + "output": { + "type": "string" + }, + "stage": { + "type": "string" + } + } + }, "codersdk.PutExtendWorkspaceRequest": { "type": "object", "required": [ diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index ef30670b3a406..0dc437f5118b4 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -757,6 +757,180 @@ } } }, + "/workspacebuilds/{workspacebuild}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Workspaces"], + "summary": "Get workspace build", + "operationId": "get-workspace-build", + "parameters": [ + { + "type": "string", + "description": "Workspace build ID", + "name": "workspacebuild", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceBuild" + } + } + } + } + }, + "/workspacebuilds/{workspacebuild}/cancel": { + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Workspaces"], + "summary": "Cancel workspace build", + "operationId": "cancel-workspace-build", + "parameters": [ + { + "type": "string", + "description": "Workspace build ID", + "name": "workspacebuild", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, + "/workspacebuilds/{workspacebuild}/logs": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Workspaces"], + "summary": "Get workspace build logs", + "operationId": "get-workspace-build-logs", + "parameters": [ + { + "type": "string", + "description": "Workspace build ID", + "name": "workspacebuild", + "in": "path", + "required": true + }, + { + "type": "integer", + "description": "Before Unix timestamp", + "name": "before", + "in": "query" + }, + { + "type": "integer", + "description": "After Unix timestamp", + "name": "after", + "in": "query" + }, + { + "type": "boolean", + "description": "Follow log stream", + "name": "follow", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.ProvisionerJobLog" + } + } + } + } + } + }, + "/workspacebuilds/{workspacebuild}/resources": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Workspaces"], + "summary": "Get workspace resources for workspace build", + "operationId": "get-workspace-resources-for-workspace-build", + "parameters": [ + { + "type": "string", + "description": "Workspace build ID", + "name": "workspacebuild", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceResource" + } + } + } + } + } + }, + "/workspacebuilds/{workspacebuild}/state": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Workspaces"], + "summary": "Get provisioner state for workspace build", + "operationId": "get-provisioner-state-for-workspace-build", + "parameters": [ + { + "type": "string", + "description": "Workspace build ID", + "name": "workspacebuild", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceBuild" + } + } + } + } + }, "/workspaces": { "get": { "security": [ @@ -1910,6 +2084,29 @@ } } }, + "codersdk.ProvisionerJobLog": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "log_level": { + "type": "string" + }, + "log_source": { + "type": "string" + }, + "output": { + "type": "string" + }, + "stage": { + "type": "string" + } + } + }, "codersdk.PutExtendWorkspaceRequest": { "type": "object", "required": ["deadline"], diff --git a/coderd/workspacebuilds.go b/coderd/workspacebuilds.go index a006c932c752b..eee08bad5ec0d 100644 --- a/coderd/workspacebuilds.go +++ b/coderd/workspacebuilds.go @@ -23,6 +23,14 @@ import ( "github.com/coder/coder/codersdk" ) +// @Summary Get workspace build +// @ID get-workspace-build +// @Security CoderSessionToken +// @Produce json +// @Tags Workspaces +// @Param workspacebuild path string true "Workspace build ID" +// @Success 200 {object} codersdk.WorkspaceBuild +// @Router /workspacebuilds/{workspacebuild} [get] func (api *API) workspaceBuild(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() workspaceBuild := httpmw.WorkspaceBuildParam(r) @@ -535,6 +543,14 @@ func (api *API) postWorkspaceBuilds(rw http.ResponseWriter, r *http.Request) { httpapi.Write(ctx, rw, http.StatusCreated, apiBuild) } +// @Summary Cancel workspace build +// @ID cancel-workspace-build +// @Security CoderSessionToken +// @Produce json +// @Tags Workspaces +// @Param workspacebuild path string true "Workspace build ID" +// @Success 200 {object} codersdk.Response +// @Router /workspacebuilds/{workspacebuild}/cancel [patch] func (api *API) patchCancelWorkspaceBuild(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() workspaceBuild := httpmw.WorkspaceBuildParam(r) @@ -630,6 +646,14 @@ func (api *API) verifyUserCanCancelWorkspaceBuilds(ctx context.Context, userID u return slices.Contains(user.RBACRoles, rbac.RoleOwner()), nil // only user with "owner" role can cancel workspace builds } +// @Summary Get workspace resources for workspace build +// @ID get-workspace-resources-for-workspace-build +// @Security CoderSessionToken +// @Produce json +// @Tags Workspaces +// @Param workspacebuild path string true "Workspace build ID" +// @Success 200 {array} codersdk.WorkspaceResource +// @Router /workspacebuilds/{workspacebuild}/resources [get] func (api *API) workspaceBuildResources(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() workspaceBuild := httpmw.WorkspaceBuildParam(r) @@ -657,6 +681,17 @@ func (api *API) workspaceBuildResources(rw http.ResponseWriter, r *http.Request) api.provisionerJobResources(rw, r, job) } +// @Summary Get workspace build logs +// @ID get-workspace-build-logs +// @Security CoderSessionToken +// @Produce json +// @Tags Workspaces +// @Param workspacebuild path string true "Workspace build ID" +// @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 /workspacebuilds/{workspacebuild}/logs [get] func (api *API) workspaceBuildLogs(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() workspaceBuild := httpmw.WorkspaceBuildParam(r) @@ -684,6 +719,14 @@ func (api *API) workspaceBuildLogs(rw http.ResponseWriter, r *http.Request) { api.provisionerJobLogs(rw, r, job) } +// @Summary Get provisioner state for workspace build +// @ID get-provisioner-state-for-workspace-build +// @Security CoderSessionToken +// @Produce json +// @Tags Workspaces +// @Param workspacebuild path string true "Workspace build ID" +// @Success 200 {object} codersdk.WorkspaceBuild +// @Router /workspacebuilds/{workspacebuild}/state [get] func (api *API) workspaceBuildState(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() workspaceBuild := httpmw.WorkspaceBuildParam(r) diff --git a/docs/api/schemas.md b/docs/api/schemas.md index 369d9d2688cc8..dddd6804a3ec0 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -2299,6 +2299,30 @@ Parameter represents a set value for the scope. | » `[any property]` | string | false | | | | `worker_id` | string | false | | | +## codersdk.ProvisionerJobLog + +```json +{ + "created_at": "string", + "id": 0, + "log_level": "string", + "log_source": "string", + "output": "string", + "stage": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ------------ | ------- | -------- | ------------ | ----------- | +| `created_at` | string | false | | | +| `id` | integer | false | | | +| `log_level` | string | false | | | +| `log_source` | string | false | | | +| `output` | string | false | | | +| `stage` | string | false | | | + ## codersdk.PutExtendWorkspaceRequest ```json diff --git a/docs/api/workspaces.md b/docs/api/workspaces.md index 4739d86a90715..0bd455c5ef8d1 100644 --- a/docs/api/workspaces.md +++ b/docs/api/workspaces.md @@ -323,6 +323,571 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/workspace/{workspacenam To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. +## Get workspace build + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild} \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /workspacebuilds/{workspacebuild}` + +### Parameters + +| Name | In | Type | Required | Description | +| ---------------- | ---- | ------ | -------- | ------------------ | +| `workspacebuild` | path | string | true | Workspace build ID | + +### Example responses + +> 200 Response + +```json +{ + "build_number": 0, + "created_at": "2019-08-24T14:15:22Z", + "daily_cost": 0, + "deadline": "2019-08-24T14:15:22Z", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3", + "initiator_name": "string", + "job": { + "canceled_at": "string", + "completed_at": "string", + "created_at": "string", + "error": "string", + "file_id": "string", + "id": "string", + "started_at": "string", + "status": "string", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "string" + }, + "reason": "string", + "resources": [ + { + "agents": [ + { + "apps": [ + { + "command": "string", + "display_name": "string", + "external": true, + "health": "string", + "healthcheck": { + "interval": 0, + "threshold": 0, + "url": "string" + }, + "icon": "string", + "id": "string", + "sharing_level": "string", + "slug": "string", + "subdomain": true, + "url": "string" + } + ], + "architecture": "string", + "connection_timeout_seconds": 0, + "created_at": "string", + "directory": "string", + "disconnected_at": "string", + "environment_variables": { + "property1": "string", + "property2": "string" + }, + "first_connected_at": "string", + "id": "string", + "instance_id": "string", + "last_connected_at": "string", + "latency": { + "property1": { + "latency_ms": 0, + "preferred": true + }, + "property2": { + "latency_ms": 0, + "preferred": true + } + }, + "name": "string", + "operating_system": "string", + "resource_id": "string", + "startup_script": "string", + "status": "string", + "troubleshooting_url": "string", + "updated_at": "string", + "version": "string" + } + ], + "created_at": "2019-08-24T14:15:22Z", + "daily_cost": 0, + "hide": true, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f", + "metadata": [ + { + "key": "string", + "sensitive": true, + "value": "string" + } + ], + "name": "string", + "type": "string", + "workspace_transition": "start" + } + ], + "status": "pending", + "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1", + "template_version_name": "string", + "transition": "start", + "updated_at": "2019-08-24T14:15:22Z", + "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9", + "workspace_name": "string", + "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7", + "workspace_owner_name": "string" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ------------------------------------------------------------ | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.WorkspaceBuild](schemas.md#codersdkworkspacebuild) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Cancel workspace build + +### Code samples + +```shell +# Example request using curl +curl -X PATCH http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/cancel \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`PATCH /workspacebuilds/{workspacebuild}/cancel` + +### Parameters + +| Name | In | Type | Required | Description | +| ---------------- | ---- | ------ | -------- | ------------------ | +| `workspacebuild` | path | string | true | Workspace build ID | + +### Example responses + +> 200 Response + +```json +{ + "detail": "string", + "message": "string", + "validations": [ + { + "detail": "string", + "field": "string" + } + ] +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ------------------------------------------------ | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.Response](schemas.md#codersdkresponse) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Get workspace build logs + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/logs \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /workspacebuilds/{workspacebuild}/logs` + +### Parameters + +| Name | In | Type | Required | Description | +| ---------------- | ----- | ------- | -------- | --------------------- | +| `workspacebuild` | path | string | true | Workspace build ID | +| `before` | query | integer | false | Before Unix timestamp | +| `after` | query | integer | false | After Unix timestamp | +| `follow` | query | boolean | false | Follow log stream | + +### Example responses + +> 200 Response + +```json +[ + { + "created_at": "string", + "id": 0, + "log_level": "string", + "log_source": "string", + "output": "string", + "stage": "string" + } +] +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | --------------------------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | array of [codersdk.ProvisionerJobLog](schemas.md#codersdkprovisionerjoblog) | + +

Response Schema

+ +Status Code **200** + +| Name | Type | Required | Restrictions | Description | +| -------------- | ------- | -------- | ------------ | ----------- | +| `[array item]` | array | false | | | +| `» created_at` | string | false | | | +| `» id` | integer | false | | | +| `» log_level` | string | false | | | +| `» log_source` | string | false | | | +| `» output` | string | false | | | +| `» stage` | string | false | | | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Get workspace resources for workspace build + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/resources \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /workspacebuilds/{workspacebuild}/resources` + +### Parameters + +| Name | In | Type | Required | Description | +| ---------------- | ---- | ------ | -------- | ------------------ | +| `workspacebuild` | path | string | true | Workspace build ID | + +### Example responses + +> 200 Response + +```json +[ + { + "agents": [ + { + "apps": [ + { + "command": "string", + "display_name": "string", + "external": true, + "health": "string", + "healthcheck": { + "interval": 0, + "threshold": 0, + "url": "string" + }, + "icon": "string", + "id": "string", + "sharing_level": "string", + "slug": "string", + "subdomain": true, + "url": "string" + } + ], + "architecture": "string", + "connection_timeout_seconds": 0, + "created_at": "string", + "directory": "string", + "disconnected_at": "string", + "environment_variables": { + "property1": "string", + "property2": "string" + }, + "first_connected_at": "string", + "id": "string", + "instance_id": "string", + "last_connected_at": "string", + "latency": { + "property1": { + "latency_ms": 0, + "preferred": true + }, + "property2": { + "latency_ms": 0, + "preferred": true + } + }, + "name": "string", + "operating_system": "string", + "resource_id": "string", + "startup_script": "string", + "status": "string", + "troubleshooting_url": "string", + "updated_at": "string", + "version": "string" + } + ], + "created_at": "2019-08-24T14:15:22Z", + "daily_cost": 0, + "hide": true, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f", + "metadata": [ + { + "key": "string", + "sensitive": true, + "value": "string" + } + ], + "name": "string", + "type": "string", + "workspace_transition": "start" + } +] +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | --------------------------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | array of [codersdk.WorkspaceResource](schemas.md#codersdkworkspaceresource) | + +

Response Schema

+ +Status Code **200** + +| Name | Type | Required | Restrictions | Description | +| ------------------------------- | ---------------------- | -------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `[array item]` | array | false | | | +| `» agents` | array | false | | | +| `»» apps` | array | false | | | +| `»»» command` | string | false | | | +| `»»» display_name` | string | false | | DisplayName is a friendly name for the app. | +| `»»» external` | boolean | false | | External specifies whether the URL should be opened externally on
the client or not. | +| `»»» health` | string | false | | | +| `»»» healthcheck` | `codersdk.Healthcheck` | false | | | +| `»»»» interval` | integer | false | | Interval specifies the seconds between each health check. | +| `»»»» threshold` | integer | false | | Threshold specifies the number of consecutive failed health checks before returning "unhealthy". | +| `»»»» url` | string | false | | URL specifies the endpoint to check for the app health. | +| `»»» icon` | string | false | | Icon is a relative path or external URL that specifies
an icon to be displayed in the dashboard. | +| `»»» id` | string | false | | | +| `»»» sharing_level` | string | false | | | +| `»»» slug` | string | false | | Slug is a unique identifier within the agent. | +| `»»» subdomain` | boolean | false | | Subdomain denotes whether the app should be accessed via a path on the
`coder server` or via a hostname-based dev URL. If this is set to true
and there is no app wildcard configured on the server, the app will not
be accessible in the UI. | +| `»»» url` | string | false | | URL is the address being proxied to inside the workspace.
If external is specified, this will be opened on the client. | +| `»» architecture` | string | false | | | +| `»» connection_timeout_seconds` | integer | false | | | +| `»» created_at` | string | false | | | +| `»» directory` | string | false | | | +| `»» disconnected_at` | string | false | | | +| `»» environment_variables` | object | false | | | +| `»»» [any property]` | string | false | | | +| `»» first_connected_at` | string | false | | | +| `»» id` | string | false | | | +| `»» instance_id` | string | false | | | +| `»» last_connected_at` | string | false | | | +| `»» latency` | object | false | | DERPLatency is mapped by region name (e.g. "New York City", "Seattle"). | +| `»»» [any property]` | `codersdk.DERPRegion` | false | | | +| `»»»» latency_ms` | number | false | | | +| `»»»» preferred` | boolean | false | | | +| `»» name` | string | false | | | +| `»» operating_system` | string | false | | | +| `»» resource_id` | string | false | | | +| `»» startup_script` | string | false | | | +| `»» status` | string | false | | | +| `»» troubleshooting_url` | string | false | | | +| `»» updated_at` | string | false | | | +| `»» version` | string | false | | | +| `» created_at` | string | false | | | +| `» daily_cost` | integer | false | | | +| `» hide` | boolean | false | | | +| `» icon` | string | false | | | +| `» id` | string | false | | | +| `» job_id` | string | false | | | +| `» metadata` | array | false | | | +| `»» key` | string | false | | | +| `»» sensitive` | boolean | false | | | +| `»» value` | string | false | | | +| `» name` | string | false | | | +| `» type` | string | false | | | +| `» workspace_transition` | string | false | | | + +#### Enumerated Values + +| Property | Value | +| ---------------------- | -------- | +| `workspace_transition` | `start` | +| `workspace_transition` | `stop` | +| `workspace_transition` | `delete` | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Get provisioner state for workspace build + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/state \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /workspacebuilds/{workspacebuild}/state` + +### Parameters + +| Name | In | Type | Required | Description | +| ---------------- | ---- | ------ | -------- | ------------------ | +| `workspacebuild` | path | string | true | Workspace build ID | + +### Example responses + +> 200 Response + +```json +{ + "build_number": 0, + "created_at": "2019-08-24T14:15:22Z", + "daily_cost": 0, + "deadline": "2019-08-24T14:15:22Z", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3", + "initiator_name": "string", + "job": { + "canceled_at": "string", + "completed_at": "string", + "created_at": "string", + "error": "string", + "file_id": "string", + "id": "string", + "started_at": "string", + "status": "string", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "string" + }, + "reason": "string", + "resources": [ + { + "agents": [ + { + "apps": [ + { + "command": "string", + "display_name": "string", + "external": true, + "health": "string", + "healthcheck": { + "interval": 0, + "threshold": 0, + "url": "string" + }, + "icon": "string", + "id": "string", + "sharing_level": "string", + "slug": "string", + "subdomain": true, + "url": "string" + } + ], + "architecture": "string", + "connection_timeout_seconds": 0, + "created_at": "string", + "directory": "string", + "disconnected_at": "string", + "environment_variables": { + "property1": "string", + "property2": "string" + }, + "first_connected_at": "string", + "id": "string", + "instance_id": "string", + "last_connected_at": "string", + "latency": { + "property1": { + "latency_ms": 0, + "preferred": true + }, + "property2": { + "latency_ms": 0, + "preferred": true + } + }, + "name": "string", + "operating_system": "string", + "resource_id": "string", + "startup_script": "string", + "status": "string", + "troubleshooting_url": "string", + "updated_at": "string", + "version": "string" + } + ], + "created_at": "2019-08-24T14:15:22Z", + "daily_cost": 0, + "hide": true, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f", + "metadata": [ + { + "key": "string", + "sensitive": true, + "value": "string" + } + ], + "name": "string", + "type": "string", + "workspace_transition": "start" + } + ], + "status": "pending", + "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1", + "template_version_name": "string", + "transition": "start", + "updated_at": "2019-08-24T14:15:22Z", + "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9", + "workspace_name": "string", + "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7", + "workspace_owner_name": "string" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ------------------------------------------------------------ | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.WorkspaceBuild](schemas.md#codersdkworkspacebuild) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + ## List workspaces ### Code samples From 96daf47a50d43af4d1251f9092f53143999c8309 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Mon, 2 Jan 2023 13:47:34 +0100 Subject: [PATCH 03/36] structs in workspacebuilds.go --- coderd/apidoc/docs.go | 50 +++++++++++--- coderd/apidoc/swagger.json | 40 ++++++++--- codersdk/provisionerdaemons.go | 22 +++--- codersdk/workspacebuilds.go | 5 +- docs/api/schemas.md | 98 ++++++++++++++++---------- docs/api/workspaces.md | 122 ++++++++++++++++++--------------- 6 files changed, 211 insertions(+), 126 deletions(-) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 8249ee27fa45d..a4fd764ceba6a 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -2261,28 +2261,42 @@ const docTemplate = `{ "type": "object", "properties": { "canceled_at": { - "type": "string" + "type": "string", + "format": "date-time" }, "completed_at": { - "type": "string" + "type": "string", + "format": "date-time" }, "created_at": { - "type": "string" + "type": "string", + "format": "date-time" }, "error": { "type": "string" }, "file_id": { - "type": "string" + "type": "string", + "format": "uuid" }, "id": { - "type": "string" + "type": "string", + "format": "uuid" }, "started_at": { - "type": "string" + "type": "string", + "format": "date-time" }, "status": { - "type": "string" + "type": "string", + "enum": [ + "pending", + "running", + "succeeded", + "canceling", + "canceled", + "failed" + ] }, "tags": { "type": "object", @@ -2291,7 +2305,8 @@ const docTemplate = `{ } }, "worker_id": { - "type": "string" + "type": "string", + "format": "uuid" } } }, @@ -2299,13 +2314,21 @@ const docTemplate = `{ "type": "object", "properties": { "created_at": { - "type": "string" + "type": "string", + "format": "date-time" }, "id": { "type": "integer" }, "log_level": { - "type": "string" + "type": "string", + "enum": [ + "trace", + "debug", + "info", + "warn", + "error" + ] }, "log_source": { "type": "string" @@ -2831,7 +2854,12 @@ const docTemplate = `{ "$ref": "#/definitions/codersdk.ProvisionerJob" }, "reason": { - "type": "string" + "type": "string", + "enum": [ + "initiator", + "autostart", + "autostop" + ] }, "resources": { "type": "array", diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 0dc437f5118b4..7e12c5beb8c1f 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -2050,28 +2050,42 @@ "type": "object", "properties": { "canceled_at": { - "type": "string" + "type": "string", + "format": "date-time" }, "completed_at": { - "type": "string" + "type": "string", + "format": "date-time" }, "created_at": { - "type": "string" + "type": "string", + "format": "date-time" }, "error": { "type": "string" }, "file_id": { - "type": "string" + "type": "string", + "format": "uuid" }, "id": { - "type": "string" + "type": "string", + "format": "uuid" }, "started_at": { - "type": "string" + "type": "string", + "format": "date-time" }, "status": { - "type": "string" + "type": "string", + "enum": [ + "pending", + "running", + "succeeded", + "canceling", + "canceled", + "failed" + ] }, "tags": { "type": "object", @@ -2080,7 +2094,8 @@ } }, "worker_id": { - "type": "string" + "type": "string", + "format": "uuid" } } }, @@ -2088,13 +2103,15 @@ "type": "object", "properties": { "created_at": { - "type": "string" + "type": "string", + "format": "date-time" }, "id": { "type": "integer" }, "log_level": { - "type": "string" + "type": "string", + "enum": ["trace", "debug", "info", "warn", "error"] }, "log_source": { "type": "string" @@ -2610,7 +2627,8 @@ "$ref": "#/definitions/codersdk.ProvisionerJob" }, "reason": { - "type": "string" + "type": "string", + "enum": ["initiator", "autostart", "autostop"] }, "resources": { "type": "array", diff --git a/codersdk/provisionerdaemons.go b/codersdk/provisionerdaemons.go index 18a771f41809b..da0d2b67d0910 100644 --- a/codersdk/provisionerdaemons.go +++ b/codersdk/provisionerdaemons.go @@ -66,24 +66,26 @@ const ( ProvisionerJobFailed ProvisionerJobStatus = "failed" ) +// ProvisionerJob describes the job executed by the provisioning daemon. type ProvisionerJob struct { - ID uuid.UUID `json:"id"` - CreatedAt time.Time `json:"created_at"` - StartedAt *time.Time `json:"started_at,omitempty"` - CompletedAt *time.Time `json:"completed_at,omitempty"` - CanceledAt *time.Time `json:"canceled_at,omitempty"` + ID uuid.UUID `json:"id" format:"uuid"` + CreatedAt time.Time `json:"created_at" format:"date-time"` + StartedAt *time.Time `json:"started_at,omitempty" format:"date-time"` + CompletedAt *time.Time `json:"completed_at,omitempty" format:"date-time"` + CanceledAt *time.Time `json:"canceled_at,omitempty" format:"date-time"` Error string `json:"error,omitempty"` - Status ProvisionerJobStatus `json:"status"` - WorkerID *uuid.UUID `json:"worker_id,omitempty"` - FileID uuid.UUID `json:"file_id"` + Status ProvisionerJobStatus `json:"status" enums:"pending,running,succeeded,canceling,canceled,failed"` + WorkerID *uuid.UUID `json:"worker_id,omitempty" format:"uuid"` + FileID uuid.UUID `json:"file_id" format:"uuid"` Tags map[string]string `json:"tags"` } +// ProvisionerJobLog represents the provisioner log entry annotated with source and level. type ProvisionerJobLog struct { ID int64 `json:"id"` - CreatedAt time.Time `json:"created_at"` + CreatedAt time.Time `json:"created_at" format:"date-time"` Source LogSource `json:"log_source"` - Level LogLevel `json:"log_level"` + Level LogLevel `json:"log_level" enums:"trace,debug,info,warn,error"` Stage string `json:"stage"` Output string `json:"output"` } diff --git a/codersdk/workspacebuilds.go b/codersdk/workspacebuilds.go index 5281710a797b0..cef31019aac7c 100644 --- a/codersdk/workspacebuilds.go +++ b/codersdk/workspacebuilds.go @@ -65,13 +65,15 @@ type WorkspaceBuild struct { InitiatorID uuid.UUID `json:"initiator_id" format:"uuid"` InitiatorUsername string `json:"initiator_name"` Job ProvisionerJob `json:"job"` - Reason BuildReason `db:"reason" json:"reason"` + Reason BuildReason `db:"reason" json:"reason" enums:"initiator,autostart,autostop"` Resources []WorkspaceResource `json:"resources"` Deadline NullTime `json:"deadline,omitempty" swaggertype:"string" format:"date-time"` Status WorkspaceStatus `json:"status" enums:"pending,starting,running,stopping,stopped,failed,canceling,canceled,deleting,deleted"` DailyCost int32 `json:"daily_cost"` } +// WorkspaceResource describes resources used to create a workspace, for instance: +// containers, images, volumes. type WorkspaceResource struct { ID uuid.UUID `json:"id" format:"uuid"` CreatedAt time.Time `json:"created_at" format:"date-time"` @@ -86,6 +88,7 @@ type WorkspaceResource struct { DailyCost int32 `json:"daily_cost"` } +// WorkspaceResourceMetadata annotates the workspace resource with custom key-value pairs. type WorkspaceResourceMetadata struct { Key string `json:"key"` Value string `json:"value"` diff --git a/docs/api/schemas.md b/docs/api/schemas.md index dddd6804a3ec0..7b4f90b58ad2c 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -2267,19 +2267,19 @@ Parameter represents a set value for the scope. ```json { - "canceled_at": "string", - "completed_at": "string", - "created_at": "string", + "canceled_at": "2019-08-24T14:15:22Z", + "completed_at": "2019-08-24T14:15:22Z", + "created_at": "2019-08-24T14:15:22Z", "error": "string", - "file_id": "string", - "id": "string", - "started_at": "string", - "status": "string", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", "tags": { "property1": "string", "property2": "string" }, - "worker_id": "string" + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" } ``` @@ -2299,13 +2299,24 @@ Parameter represents a set value for the scope. | » `[any property]` | string | false | | | | `worker_id` | string | false | | | +#### Enumerated Values + +| Property | Value | +| -------- | ----------- | +| `status` | `pending` | +| `status` | `running` | +| `status` | `succeeded` | +| `status` | `canceling` | +| `status` | `canceled` | +| `status` | `failed` | + ## codersdk.ProvisionerJobLog ```json { - "created_at": "string", + "created_at": "2019-08-24T14:15:22Z", "id": 0, - "log_level": "string", + "log_level": "trace", "log_source": "string", "output": "string", "stage": "string" @@ -2323,6 +2334,16 @@ Parameter represents a set value for the scope. | `output` | string | false | | | | `stage` | string | false | | | +#### Enumerated Values + +| Property | Value | +| ----------- | ------- | +| `log_level` | `trace` | +| `log_level` | `debug` | +| `log_level` | `info` | +| `log_level` | `warn` | +| `log_level` | `error` | + ## codersdk.PutExtendWorkspaceRequest ```json @@ -2862,21 +2883,21 @@ Parameter represents a set value for the scope. "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3", "initiator_name": "string", "job": { - "canceled_at": "string", - "completed_at": "string", - "created_at": "string", + "canceled_at": "2019-08-24T14:15:22Z", + "completed_at": "2019-08-24T14:15:22Z", + "created_at": "2019-08-24T14:15:22Z", "error": "string", - "file_id": "string", - "id": "string", - "started_at": "string", - "status": "string", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", "tags": { "property1": "string", "property2": "string" }, - "worker_id": "string" + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" }, - "reason": "string", + "reason": "initiator", "resources": [ { "agents": [ @@ -3130,21 +3151,21 @@ Parameter represents a set value for the scope. "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3", "initiator_name": "string", "job": { - "canceled_at": "string", - "completed_at": "string", - "created_at": "string", + "canceled_at": "2019-08-24T14:15:22Z", + "completed_at": "2019-08-24T14:15:22Z", + "created_at": "2019-08-24T14:15:22Z", "error": "string", - "file_id": "string", - "id": "string", - "started_at": "string", - "status": "string", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", "tags": { "property1": "string", "property2": "string" }, - "worker_id": "string" + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" }, - "reason": "string", + "reason": "initiator", "resources": [ { "agents": [ @@ -3259,6 +3280,9 @@ Parameter represents a set value for the scope. | Property | Value | | ------------ | ----------- | +| `reason` | `initiator` | +| `reason` | `autostart` | +| `reason` | `autostop` | | `status` | `pending` | | `status` | `starting` | | `status` | `running` | @@ -3412,21 +3436,21 @@ Parameter represents a set value for the scope. "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3", "initiator_name": "string", "job": { - "canceled_at": "string", - "completed_at": "string", - "created_at": "string", + "canceled_at": "2019-08-24T14:15:22Z", + "completed_at": "2019-08-24T14:15:22Z", + "created_at": "2019-08-24T14:15:22Z", "error": "string", - "file_id": "string", - "id": "string", - "started_at": "string", - "status": "string", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", "tags": { "property1": "string", "property2": "string" }, - "worker_id": "string" + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" }, - "reason": "string", + "reason": "initiator", "resources": [ { "agents": [ diff --git a/docs/api/workspaces.md b/docs/api/workspaces.md index 0bd455c5ef8d1..018936efd2851 100644 --- a/docs/api/workspaces.md +++ b/docs/api/workspaces.md @@ -41,21 +41,21 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/member "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3", "initiator_name": "string", "job": { - "canceled_at": "string", - "completed_at": "string", - "created_at": "string", + "canceled_at": "2019-08-24T14:15:22Z", + "completed_at": "2019-08-24T14:15:22Z", + "created_at": "2019-08-24T14:15:22Z", "error": "string", - "file_id": "string", - "id": "string", - "started_at": "string", - "status": "string", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", "tags": { "property1": "string", "property2": "string" }, - "worker_id": "string" + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" }, - "reason": "string", + "reason": "initiator", "resources": [ { "agents": [ @@ -202,21 +202,21 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/workspace/{workspacenam "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3", "initiator_name": "string", "job": { - "canceled_at": "string", - "completed_at": "string", - "created_at": "string", + "canceled_at": "2019-08-24T14:15:22Z", + "completed_at": "2019-08-24T14:15:22Z", + "created_at": "2019-08-24T14:15:22Z", "error": "string", - "file_id": "string", - "id": "string", - "started_at": "string", - "status": "string", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", "tags": { "property1": "string", "property2": "string" }, - "worker_id": "string" + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" }, - "reason": "string", + "reason": "initiator", "resources": [ { "agents": [ @@ -356,21 +356,21 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild} \ "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3", "initiator_name": "string", "job": { - "canceled_at": "string", - "completed_at": "string", - "created_at": "string", + "canceled_at": "2019-08-24T14:15:22Z", + "completed_at": "2019-08-24T14:15:22Z", + "created_at": "2019-08-24T14:15:22Z", "error": "string", - "file_id": "string", - "id": "string", - "started_at": "string", - "status": "string", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", "tags": { "property1": "string", "property2": "string" }, - "worker_id": "string" + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" }, - "reason": "string", + "reason": "initiator", "resources": [ { "agents": [ @@ -538,9 +538,9 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/log ```json [ { - "created_at": "string", + "created_at": "2019-08-24T14:15:22Z", "id": 0, - "log_level": "string", + "log_level": "trace", "log_source": "string", "output": "string", "stage": "string" @@ -568,6 +568,16 @@ Status Code **200** | `» output` | string | false | | | | `» stage` | string | false | | | +#### Enumerated Values + +| Property | Value | +| ----------- | ------- | +| `log_level` | `trace` | +| `log_level` | `debug` | +| `log_level` | `info` | +| `log_level` | `warn` | +| `log_level` | `error` | + To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. ## Get workspace resources for workspace build @@ -779,21 +789,21 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/sta "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3", "initiator_name": "string", "job": { - "canceled_at": "string", - "completed_at": "string", - "created_at": "string", + "canceled_at": "2019-08-24T14:15:22Z", + "completed_at": "2019-08-24T14:15:22Z", + "created_at": "2019-08-24T14:15:22Z", "error": "string", - "file_id": "string", - "id": "string", - "started_at": "string", - "status": "string", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", "tags": { "property1": "string", "property2": "string" }, - "worker_id": "string" + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" }, - "reason": "string", + "reason": "initiator", "resources": [ { "agents": [ @@ -951,21 +961,21 @@ curl -X GET http://coder-server:8080/api/v2/workspaces \ "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3", "initiator_name": "string", "job": { - "canceled_at": "string", - "completed_at": "string", - "created_at": "string", + "canceled_at": "2019-08-24T14:15:22Z", + "completed_at": "2019-08-24T14:15:22Z", + "created_at": "2019-08-24T14:15:22Z", "error": "string", - "file_id": "string", - "id": "string", - "started_at": "string", - "status": "string", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", "tags": { "property1": "string", "property2": "string" }, - "worker_id": "string" + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" }, - "reason": "string", + "reason": "initiator", "resources": [ { "agents": [ @@ -1109,21 +1119,21 @@ curl -X GET http://coder-server:8080/api/v2/workspaces/{id} \ "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3", "initiator_name": "string", "job": { - "canceled_at": "string", - "completed_at": "string", - "created_at": "string", + "canceled_at": "2019-08-24T14:15:22Z", + "completed_at": "2019-08-24T14:15:22Z", + "created_at": "2019-08-24T14:15:22Z", "error": "string", - "file_id": "string", - "id": "string", - "started_at": "string", - "status": "string", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", "tags": { "property1": "string", "property2": "string" }, - "worker_id": "string" + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" }, - "reason": "string", + "reason": "initiator", "resources": [ { "agents": [ From 663ec87a0e00bbb01f6428a43e961ef929d56de9 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Mon, 2 Jan 2023 15:12:24 +0100 Subject: [PATCH 04/36] workspaceagents: instance identity --- coderd/apidoc/docs.go | 157 ++++++++++++++++++++++++++++++++ coderd/apidoc/swagger.json | 137 ++++++++++++++++++++++++++++ coderd/workspaceresourceauth.go | 27 ++++++ docs/api/schemas.md | 60 ++++++++++++ docs/api/workspaces.md | 140 ++++++++++++++++++++++++++++ 5 files changed, 521 insertions(+) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index a4fd764ceba6a..710633ba96e48 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -875,6 +875,114 @@ const docTemplate = `{ } } }, + "/workspaceagents/aws-instance-identity": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Workspaces" + ], + "summary": "Authenticate agent on AWS instance", + "operationId": "authenticate-agent-on-aws-instance", + "parameters": [ + { + "description": "Instance identity token", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.AWSInstanceIdentityToken" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceAgentAuthenticateResponse" + } + } + } + } + }, + "/workspaceagents/azure-instance-identity": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Workspaces" + ], + "summary": "Authenticate agent on Azure instance", + "operationId": "authenticate-agent-on-azure-instance", + "parameters": [ + { + "description": "Instance identity token", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.AzureInstanceIdentityToken" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceAgentAuthenticateResponse" + } + } + } + } + }, + "/workspaceagents/google-instance-identity": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Workspaces" + ], + "summary": "Authenticate agent on Google Cloud instance", + "operationId": "authenticate-agent-on-google-cloud-instance", + "parameters": [ + { + "description": "Instance identity token", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.GoogleInstanceIdentityToken" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceAgentAuthenticateResponse" + } + } + } + } + }, "/workspacebuilds/{workspacebuild}": { "get": { "security": [ @@ -1409,6 +1517,21 @@ const docTemplate = `{ } } }, + "codersdk.AWSInstanceIdentityToken": { + "type": "object", + "required": [ + "document", + "signature" + ], + "properties": { + "document": { + "type": "string" + }, + "signature": { + "type": "string" + } + } + }, "codersdk.AuditDiff": { "type": "object", "additionalProperties": { @@ -1561,6 +1684,21 @@ const docTemplate = `{ "type": "boolean" } }, + "codersdk.AzureInstanceIdentityToken": { + "type": "object", + "required": [ + "encoding", + "signature" + ], + "properties": { + "encoding": { + "type": "string" + }, + "signature": { + "type": "string" + } + } + }, "codersdk.BuildInfoResponse": { "type": "object", "properties": { @@ -2095,6 +2233,17 @@ const docTemplate = `{ } } }, + "codersdk.GoogleInstanceIdentityToken": { + "type": "object", + "required": [ + "json_web_token" + ], + "properties": { + "json_web_token": { + "type": "string" + } + } + }, "codersdk.Healthcheck": { "type": "object", "properties": { @@ -2777,6 +2926,14 @@ const docTemplate = `{ } } }, + "codersdk.WorkspaceAgentAuthenticateResponse": { + "type": "object", + "properties": { + "session_token": { + "type": "string" + } + } + }, "codersdk.WorkspaceApp": { "type": "object", "properties": { diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 7e12c5beb8c1f..67065b7260f6d 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -757,6 +757,102 @@ } } }, + "/workspaceagents/aws-instance-identity": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Workspaces"], + "summary": "Authenticate agent on AWS instance", + "operationId": "authenticate-agent-on-aws-instance", + "parameters": [ + { + "description": "Instance identity token", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.AWSInstanceIdentityToken" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceAgentAuthenticateResponse" + } + } + } + } + }, + "/workspaceagents/azure-instance-identity": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Workspaces"], + "summary": "Authenticate agent on Azure instance", + "operationId": "authenticate-agent-on-azure-instance", + "parameters": [ + { + "description": "Instance identity token", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.AzureInstanceIdentityToken" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceAgentAuthenticateResponse" + } + } + } + } + }, + "/workspaceagents/google-instance-identity": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Workspaces"], + "summary": "Authenticate agent on Google Cloud instance", + "operationId": "authenticate-agent-on-google-cloud-instance", + "parameters": [ + { + "description": "Instance identity token", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.GoogleInstanceIdentityToken" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceAgentAuthenticateResponse" + } + } + } + } + }, "/workspacebuilds/{workspacebuild}": { "get": { "security": [ @@ -1230,6 +1326,18 @@ } } }, + "codersdk.AWSInstanceIdentityToken": { + "type": "object", + "required": ["document", "signature"], + "properties": { + "document": { + "type": "string" + }, + "signature": { + "type": "string" + } + } + }, "codersdk.AuditDiff": { "type": "object", "additionalProperties": { @@ -1377,6 +1485,18 @@ "type": "boolean" } }, + "codersdk.AzureInstanceIdentityToken": { + "type": "object", + "required": ["encoding", "signature"], + "properties": { + "encoding": { + "type": "string" + }, + "signature": { + "type": "string" + } + } + }, "codersdk.BuildInfoResponse": { "type": "object", "properties": { @@ -1895,6 +2015,15 @@ } } }, + "codersdk.GoogleInstanceIdentityToken": { + "type": "object", + "required": ["json_web_token"], + "properties": { + "json_web_token": { + "type": "string" + } + } + }, "codersdk.Healthcheck": { "type": "object", "properties": { @@ -2550,6 +2679,14 @@ } } }, + "codersdk.WorkspaceAgentAuthenticateResponse": { + "type": "object", + "properties": { + "session_token": { + "type": "string" + } + } + }, "codersdk.WorkspaceApp": { "type": "object", "properties": { diff --git a/coderd/workspaceresourceauth.go b/coderd/workspaceresourceauth.go index 84923fd33db00..396d324ff6389 100644 --- a/coderd/workspaceresourceauth.go +++ b/coderd/workspaceresourceauth.go @@ -19,6 +19,15 @@ import ( // Azure supports instance identity verification: // https://docs.microsoft.com/en-us/azure/virtual-machines/windows/instance-metadata-service?tabs=linux#tabgroup_14 +// +// @Summary Authenticate agent on Azure instance +// @ID authenticate-agent-on-azure-instance +// @Security CoderSessionToken +// @Produce json +// @Tags Workspaces +// @Param request body codersdk.AzureInstanceIdentityToken true "Instance identity token" +// @Success 200 {object} codersdk.WorkspaceAgentAuthenticateResponse +// @Router /workspaceagents/azure-instance-identity [post] func (api *API) postWorkspaceAuthAzureInstanceIdentity(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() var req codersdk.AzureInstanceIdentityToken @@ -39,6 +48,15 @@ func (api *API) postWorkspaceAuthAzureInstanceIdentity(rw http.ResponseWriter, r // 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 +// @Produce json +// @Tags Workspaces +// @Param request body codersdk.AWSInstanceIdentityToken true "Instance identity token" +// @Success 200 {object} codersdk.WorkspaceAgentAuthenticateResponse +// @Router /workspaceagents/aws-instance-identity [post] func (api *API) postWorkspaceAuthAWSInstanceIdentity(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() var req codersdk.AWSInstanceIdentityToken @@ -59,6 +77,15 @@ func (api *API) postWorkspaceAuthAWSInstanceIdentity(rw http.ResponseWriter, r * // 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 +// @Produce json +// @Tags Workspaces +// @Param request body codersdk.GoogleInstanceIdentityToken true "Instance identity token" +// @Success 200 {object} codersdk.WorkspaceAgentAuthenticateResponse +// @Router /workspaceagents/google-instance-identity [post] func (api *API) postWorkspaceAuthGoogleInstanceIdentity(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() var req codersdk.GoogleInstanceIdentityToken diff --git a/docs/api/schemas.md b/docs/api/schemas.md index 7b4f90b58ad2c..f7bf566b09612 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -16,6 +16,22 @@ | ------------ | ------ | -------- | ------------ | ----------- | | `csp-report` | object | false | | | +## codersdk.AWSInstanceIdentityToken + +```json +{ + "document": "string", + "signature": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ----------- | ------ | -------- | ------------ | ----------- | +| `document` | string | true | | | +| `signature` | string | true | | | + ## codersdk.AuditDiff ```json @@ -297,6 +313,22 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in | ---------------- | ------- | -------- | ------------ | ----------- | | `[any property]` | boolean | false | | | +## codersdk.AzureInstanceIdentityToken + +```json +{ + "encoding": "string", + "signature": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ----------- | ------ | -------- | ------------ | ----------- | +| `encoding` | string | true | | | +| `signature` | string | true | | | + ## codersdk.BuildInfoResponse ```json @@ -1786,6 +1818,20 @@ CreateParameterRequest is a structure used to create a new parameter value for a | `type` | string | false | | | | `validate_url` | string | false | | | +## codersdk.GoogleInstanceIdentityToken + +```json +{ + "json_web_token": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ---------------- | ------ | -------- | ------------ | ----------- | +| `json_web_token` | string | true | | | + ## codersdk.Healthcheck ```json @@ -3101,6 +3147,20 @@ Parameter represents a set value for the scope. | `updated_at` | string | false | | | | `version` | string | false | | | +## codersdk.WorkspaceAgentAuthenticateResponse + +```json +{ + "session_token": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| --------------- | ------ | -------- | ------------ | ----------- | +| `session_token` | string | false | | | + ## codersdk.WorkspaceApp ```json diff --git a/docs/api/workspaces.md b/docs/api/workspaces.md index 018936efd2851..2e0ae40e7ff9e 100644 --- a/docs/api/workspaces.md +++ b/docs/api/workspaces.md @@ -323,6 +323,146 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/workspace/{workspacenam To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. +## Authenticate agent on AWS instance + +### Code samples + +```shell +# Example request using curl +curl -X POST http://coder-server:8080/api/v2/workspaceagents/aws-instance-identity \ + -H 'Content-Type: application/json' \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`POST /workspaceagents/aws-instance-identity` + +> Body parameter + +```json +{ + "document": "string", + "signature": "string" +} +``` + +### Parameters + +| Name | In | Type | Required | Description | +| ------ | ---- | -------------------------------------------------------------------------------- | -------- | ----------------------- | +| `body` | body | [codersdk.AWSInstanceIdentityToken](schemas.md#codersdkawsinstanceidentitytoken) | true | Instance identity token | + +### Example responses + +> 200 Response + +```json +{ + "session_token": "string" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ---------------------------------------------------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.WorkspaceAgentAuthenticateResponse](schemas.md#codersdkworkspaceagentauthenticateresponse) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Authenticate agent on Azure instance + +### Code samples + +```shell +# Example request using curl +curl -X POST http://coder-server:8080/api/v2/workspaceagents/azure-instance-identity \ + -H 'Content-Type: application/json' \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`POST /workspaceagents/azure-instance-identity` + +> Body parameter + +```json +{ + "encoding": "string", + "signature": "string" +} +``` + +### Parameters + +| Name | In | Type | Required | Description | +| ------ | ---- | ------------------------------------------------------------------------------------ | -------- | ----------------------- | +| `body` | body | [codersdk.AzureInstanceIdentityToken](schemas.md#codersdkazureinstanceidentitytoken) | true | Instance identity token | + +### Example responses + +> 200 Response + +```json +{ + "session_token": "string" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ---------------------------------------------------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.WorkspaceAgentAuthenticateResponse](schemas.md#codersdkworkspaceagentauthenticateresponse) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Authenticate agent on Google Cloud instance + +### Code samples + +```shell +# Example request using curl +curl -X POST http://coder-server:8080/api/v2/workspaceagents/google-instance-identity \ + -H 'Content-Type: application/json' \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`POST /workspaceagents/google-instance-identity` + +> Body parameter + +```json +{ + "json_web_token": "string" +} +``` + +### Parameters + +| Name | In | Type | Required | Description | +| ------ | ---- | -------------------------------------------------------------------------------------- | -------- | ----------------------- | +| `body` | body | [codersdk.GoogleInstanceIdentityToken](schemas.md#codersdkgoogleinstanceidentitytoken) | true | Instance identity token | + +### Example responses + +> 200 Response + +```json +{ + "session_token": "string" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ---------------------------------------------------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.WorkspaceAgentAuthenticateResponse](schemas.md#codersdkworkspaceagentauthenticateresponse) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + ## Get workspace build ### Code samples From fc00d7e10aec7f6b5f87b369f490fa4d4065b605 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Mon, 2 Jan 2023 15:44:40 +0100 Subject: [PATCH 05/36] workspaceagents.go in progress --- coderd/apidoc/docs.go | 210 ++++++++++++++++-- coderd/apidoc/swagger.json | 195 +++++++++++++++-- coderd/workspaceagents.go | 8 + coderd/workspaceresourceauth.go | 6 +- codersdk/workspaceagents.go | 16 +- codersdk/workspaceapps.go | 4 +- docs/api/agents.md | 252 ++++++++++++++++++++++ docs/api/schemas.md | 370 +++++++++++++++++++++++++++----- docs/api/workspaces.md | 297 +++++++------------------ docs/manifest.json | 4 + 10 files changed, 1056 insertions(+), 306 deletions(-) create mode 100644 docs/api/agents.md diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 710633ba96e48..b8180c96821b4 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -886,7 +886,7 @@ const docTemplate = `{ "application/json" ], "tags": [ - "Workspaces" + "Agents" ], "summary": "Authenticate agent on AWS instance", "operationId": "authenticate-agent-on-aws-instance", @@ -922,7 +922,7 @@ const docTemplate = `{ "application/json" ], "tags": [ - "Workspaces" + "Agents" ], "summary": "Authenticate agent on Azure instance", "operationId": "authenticate-agent-on-azure-instance", @@ -958,7 +958,7 @@ const docTemplate = `{ "application/json" ], "tags": [ - "Workspaces" + "Agents" ], "summary": "Authenticate agent on Google Cloud instance", "operationId": "authenticate-agent-on-google-cloud-instance", @@ -983,6 +983,34 @@ const docTemplate = `{ } } }, + "/workspaceagents/me/metadata": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Agents" + ], + "summary": "Get authorized workspace agent metadata", + "operationId": "get-authorized-workspace-agent-metadata", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceAgentMetadata" + } + } + } + } + }, "/workspacebuilds/{workspacebuild}": { "get": { "security": [ @@ -2867,13 +2895,15 @@ const docTemplate = `{ "type": "integer" }, "created_at": { - "type": "string" + "type": "string", + "format": "date-time" }, "directory": { "type": "string" }, "disconnected_at": { - "type": "string" + "type": "string", + "format": "date-time" }, "environment_variables": { "type": "object", @@ -2882,16 +2912,19 @@ const docTemplate = `{ } }, "first_connected_at": { - "type": "string" + "type": "string", + "format": "date-time" }, "id": { - "type": "string" + "type": "string", + "format": "uuid" }, "instance_id": { "type": "string" }, "last_connected_at": { - "type": "string" + "type": "string", + "format": "date-time" }, "latency": { "description": "DERPLatency is mapped by region name (e.g. \"New York City\", \"Seattle\").", @@ -2907,19 +2940,27 @@ const docTemplate = `{ "type": "string" }, "resource_id": { - "type": "string" + "type": "string", + "format": "uuid" }, "startup_script": { "type": "string" }, "status": { - "type": "string" + "type": "string", + "enum": [ + "connecting", + "connected", + "disconnected", + "timeout" + ] }, "troubleshooting_url": { "type": "string" }, "updated_at": { - "type": "string" + "type": "string", + "format": "date-time" }, "version": { "type": "string" @@ -2934,6 +2975,42 @@ const docTemplate = `{ } } }, + "codersdk.WorkspaceAgentMetadata": { + "type": "object", + "properties": { + "apps": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceApp" + } + }, + "derpmap": { + "$ref": "#/definitions/tailcfg.DERPMap" + }, + "directory": { + "type": "string" + }, + "environment_variables": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "git_auth_configs": { + "description": "GitAuthConfigs stores the number of Git configurations\nthe Coder deployment has. If this number is \u003e0, we\nset up special configuration in the workspace.", + "type": "integer" + }, + "motd_file": { + "type": "string" + }, + "startup_script": { + "type": "string" + }, + "vscode_port_proxy_uri": { + "type": "string" + } + } + }, "codersdk.WorkspaceApp": { "type": "object", "properties": { @@ -2960,10 +3037,16 @@ const docTemplate = `{ "type": "string" }, "id": { - "type": "string" + "type": "string", + "format": "uuid" }, "sharing_level": { - "type": "string" + "type": "string", + "enum": [ + "owner", + "authenticated", + "public" + ] }, "slug": { "description": "Slug is a unique identifier within the agent.", @@ -3156,6 +3239,107 @@ const docTemplate = `{ }, "netip.Addr": { "type": "object" + }, + "tailcfg.DERPMap": { + "type": "object", + "properties": { + "omitDefaultRegions": { + "description": "OmitDefaultRegions specifies to not use Tailscale's DERP servers, and only use those\nspecified in this DERPMap. If there are none set outside of the defaults, this is a noop.", + "type": "boolean" + }, + "regions": { + "description": "Regions is the set of geographic regions running DERP node(s).\n\nIt's keyed by the DERPRegion.RegionID.\n\nThe numbers are not necessarily contiguous.", + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/tailcfg.DERPRegion" + } + } + } + }, + "tailcfg.DERPNode": { + "type": "object", + "properties": { + "certName": { + "description": "CertName optionally specifies the expected TLS cert common\nname. If empty, HostName is used. If CertName is non-empty,\nHostName is only used for the TCP dial (if IPv4/IPv6 are\nnot present) + TLS ClientHello.", + "type": "string" + }, + "derpport": { + "description": "DERPPort optionally provides an alternate TLS port number\nfor the DERP HTTPS server.\n\nIf zero, 443 is used.", + "type": "integer" + }, + "forceHTTP": { + "description": "ForceHTTP is used by unit tests to force HTTP.\nIt should not be set by users.", + "type": "boolean" + }, + "hostName": { + "description": "HostName is the DERP node's hostname.\n\nIt is required but need not be unique; multiple nodes may\nhave the same HostName but vary in configuration otherwise.", + "type": "string" + }, + "insecureForTests": { + "description": "InsecureForTests is used by unit tests to disable TLS verification.\nIt should not be set by users.", + "type": "boolean" + }, + "ipv4": { + "description": "IPv4 optionally forces an IPv4 address to use, instead of using DNS.\nIf empty, A record(s) from DNS lookups of HostName are used.\nIf the string is not an IPv4 address, IPv4 is not used; the\nconventional string to disable IPv4 (and not use DNS) is\n\"none\".", + "type": "string" + }, + "ipv6": { + "description": "IPv6 optionally forces an IPv6 address to use, instead of using DNS.\nIf empty, AAAA record(s) from DNS lookups of HostName are used.\nIf the string is not an IPv6 address, IPv6 is not used; the\nconventional string to disable IPv6 (and not use DNS) is\n\"none\".", + "type": "string" + }, + "name": { + "description": "Name is a unique node name (across all regions).\nIt is not a host name.\nIt's typically of the form \"1b\", \"2a\", \"3b\", etc. (region\nID + suffix within that region)", + "type": "string" + }, + "regionID": { + "description": "RegionID is the RegionID of the DERPRegion that this node\nis running in.", + "type": "integer" + }, + "stunonly": { + "description": "STUNOnly marks a node as only a STUN server and not a DERP\nserver.", + "type": "boolean" + }, + "stunport": { + "description": "Port optionally specifies a STUN port to use.\nZero means 3478.\nTo disable STUN on this node, use -1.", + "type": "integer" + }, + "stuntestIP": { + "description": "STUNTestIP is used in tests to override the STUN server's IP.\nIf empty, it's assumed to be the same as the DERP server.", + "type": "string" + } + } + }, + "tailcfg.DERPRegion": { + "type": "object", + "properties": { + "avoid": { + "description": "Avoid is whether the client should avoid picking this as its home\nregion. The region should only be used if a peer is there.\nClients already using this region as their home should migrate\naway to a new region without Avoid set.", + "type": "boolean" + }, + "embeddedRelay": { + "description": "EmbeddedRelay is true when the region is bundled with the Coder\ncontrol plane.", + "type": "boolean" + }, + "nodes": { + "description": "Nodes are the DERP nodes running in this region, in\npriority order for the current client. Client TLS\nconnections should ideally only go to the first entry\n(falling back to the second if necessary). STUN packets\nshould go to the first 1 or 2.\n\nIf nodes within a region route packets amongst themselves,\nbut not to other regions. That said, each user/domain\nshould get a the same preferred node order, so if all nodes\nfor a user/network pick the first one (as they should, when\nthings are healthy), the inter-cluster routing is minimal\nto zero.", + "type": "array", + "items": { + "$ref": "#/definitions/tailcfg.DERPNode" + } + }, + "regionCode": { + "description": "RegionCode is a short name for the region. It's usually a popular\ncity or airport code in the region: \"nyc\", \"sf\", \"sin\",\n\"fra\", etc.", + "type": "string" + }, + "regionID": { + "description": "RegionID is a unique integer for a geographic region.\n\nIt corresponds to the legacy derpN.tailscale.com hostnames\nused by older clients. (Older clients will continue to resolve\nderpN.tailscale.com when contacting peers, rather than use\nthe server-provided DERPMap)\n\nRegionIDs must be non-zero, positive, and guaranteed to fit\nin a JavaScript number.\n\nRegionIDs in range 900-999 are reserved for end users to run their\nown DERP nodes.", + "type": "integer" + }, + "regionName": { + "description": "RegionName is a long English name for the region: \"New York City\",\n\"San Francisco\", \"Singapore\", \"Frankfurt\", etc.", + "type": "string" + } + } } }, "securityDefinitions": { diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 67065b7260f6d..4ddae97c7e83a 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -765,7 +765,7 @@ } ], "produces": ["application/json"], - "tags": ["Workspaces"], + "tags": ["Agents"], "summary": "Authenticate agent on AWS instance", "operationId": "authenticate-agent-on-aws-instance", "parameters": [ @@ -797,7 +797,7 @@ } ], "produces": ["application/json"], - "tags": ["Workspaces"], + "tags": ["Agents"], "summary": "Authenticate agent on Azure instance", "operationId": "authenticate-agent-on-azure-instance", "parameters": [ @@ -829,7 +829,7 @@ } ], "produces": ["application/json"], - "tags": ["Workspaces"], + "tags": ["Agents"], "summary": "Authenticate agent on Google Cloud instance", "operationId": "authenticate-agent-on-google-cloud-instance", "parameters": [ @@ -853,6 +853,28 @@ } } }, + "/workspaceagents/me/metadata": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Agents"], + "summary": "Get authorized workspace agent metadata", + "operationId": "get-authorized-workspace-agent-metadata", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceAgentMetadata" + } + } + } + } + }, "/workspacebuilds/{workspacebuild}": { "get": { "security": [ @@ -2620,13 +2642,15 @@ "type": "integer" }, "created_at": { - "type": "string" + "type": "string", + "format": "date-time" }, "directory": { "type": "string" }, "disconnected_at": { - "type": "string" + "type": "string", + "format": "date-time" }, "environment_variables": { "type": "object", @@ -2635,16 +2659,19 @@ } }, "first_connected_at": { - "type": "string" + "type": "string", + "format": "date-time" }, "id": { - "type": "string" + "type": "string", + "format": "uuid" }, "instance_id": { "type": "string" }, "last_connected_at": { - "type": "string" + "type": "string", + "format": "date-time" }, "latency": { "description": "DERPLatency is mapped by region name (e.g. \"New York City\", \"Seattle\").", @@ -2660,19 +2687,22 @@ "type": "string" }, "resource_id": { - "type": "string" + "type": "string", + "format": "uuid" }, "startup_script": { "type": "string" }, "status": { - "type": "string" + "type": "string", + "enum": ["connecting", "connected", "disconnected", "timeout"] }, "troubleshooting_url": { "type": "string" }, "updated_at": { - "type": "string" + "type": "string", + "format": "date-time" }, "version": { "type": "string" @@ -2687,6 +2717,42 @@ } } }, + "codersdk.WorkspaceAgentMetadata": { + "type": "object", + "properties": { + "apps": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceApp" + } + }, + "derpmap": { + "$ref": "#/definitions/tailcfg.DERPMap" + }, + "directory": { + "type": "string" + }, + "environment_variables": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "git_auth_configs": { + "description": "GitAuthConfigs stores the number of Git configurations\nthe Coder deployment has. If this number is \u003e0, we\nset up special configuration in the workspace.", + "type": "integer" + }, + "motd_file": { + "type": "string" + }, + "startup_script": { + "type": "string" + }, + "vscode_port_proxy_uri": { + "type": "string" + } + } + }, "codersdk.WorkspaceApp": { "type": "object", "properties": { @@ -2713,10 +2779,12 @@ "type": "string" }, "id": { - "type": "string" + "type": "string", + "format": "uuid" }, "sharing_level": { - "type": "string" + "type": "string", + "enum": ["owner", "authenticated", "public"] }, "slug": { "description": "Slug is a unique identifier within the agent.", @@ -2897,6 +2965,107 @@ }, "netip.Addr": { "type": "object" + }, + "tailcfg.DERPMap": { + "type": "object", + "properties": { + "omitDefaultRegions": { + "description": "OmitDefaultRegions specifies to not use Tailscale's DERP servers, and only use those\nspecified in this DERPMap. If there are none set outside of the defaults, this is a noop.", + "type": "boolean" + }, + "regions": { + "description": "Regions is the set of geographic regions running DERP node(s).\n\nIt's keyed by the DERPRegion.RegionID.\n\nThe numbers are not necessarily contiguous.", + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/tailcfg.DERPRegion" + } + } + } + }, + "tailcfg.DERPNode": { + "type": "object", + "properties": { + "certName": { + "description": "CertName optionally specifies the expected TLS cert common\nname. If empty, HostName is used. If CertName is non-empty,\nHostName is only used for the TCP dial (if IPv4/IPv6 are\nnot present) + TLS ClientHello.", + "type": "string" + }, + "derpport": { + "description": "DERPPort optionally provides an alternate TLS port number\nfor the DERP HTTPS server.\n\nIf zero, 443 is used.", + "type": "integer" + }, + "forceHTTP": { + "description": "ForceHTTP is used by unit tests to force HTTP.\nIt should not be set by users.", + "type": "boolean" + }, + "hostName": { + "description": "HostName is the DERP node's hostname.\n\nIt is required but need not be unique; multiple nodes may\nhave the same HostName but vary in configuration otherwise.", + "type": "string" + }, + "insecureForTests": { + "description": "InsecureForTests is used by unit tests to disable TLS verification.\nIt should not be set by users.", + "type": "boolean" + }, + "ipv4": { + "description": "IPv4 optionally forces an IPv4 address to use, instead of using DNS.\nIf empty, A record(s) from DNS lookups of HostName are used.\nIf the string is not an IPv4 address, IPv4 is not used; the\nconventional string to disable IPv4 (and not use DNS) is\n\"none\".", + "type": "string" + }, + "ipv6": { + "description": "IPv6 optionally forces an IPv6 address to use, instead of using DNS.\nIf empty, AAAA record(s) from DNS lookups of HostName are used.\nIf the string is not an IPv6 address, IPv6 is not used; the\nconventional string to disable IPv6 (and not use DNS) is\n\"none\".", + "type": "string" + }, + "name": { + "description": "Name is a unique node name (across all regions).\nIt is not a host name.\nIt's typically of the form \"1b\", \"2a\", \"3b\", etc. (region\nID + suffix within that region)", + "type": "string" + }, + "regionID": { + "description": "RegionID is the RegionID of the DERPRegion that this node\nis running in.", + "type": "integer" + }, + "stunonly": { + "description": "STUNOnly marks a node as only a STUN server and not a DERP\nserver.", + "type": "boolean" + }, + "stunport": { + "description": "Port optionally specifies a STUN port to use.\nZero means 3478.\nTo disable STUN on this node, use -1.", + "type": "integer" + }, + "stuntestIP": { + "description": "STUNTestIP is used in tests to override the STUN server's IP.\nIf empty, it's assumed to be the same as the DERP server.", + "type": "string" + } + } + }, + "tailcfg.DERPRegion": { + "type": "object", + "properties": { + "avoid": { + "description": "Avoid is whether the client should avoid picking this as its home\nregion. The region should only be used if a peer is there.\nClients already using this region as their home should migrate\naway to a new region without Avoid set.", + "type": "boolean" + }, + "embeddedRelay": { + "description": "EmbeddedRelay is true when the region is bundled with the Coder\ncontrol plane.", + "type": "boolean" + }, + "nodes": { + "description": "Nodes are the DERP nodes running in this region, in\npriority order for the current client. Client TLS\nconnections should ideally only go to the first entry\n(falling back to the second if necessary). STUN packets\nshould go to the first 1 or 2.\n\nIf nodes within a region route packets amongst themselves,\nbut not to other regions. That said, each user/domain\nshould get a the same preferred node order, so if all nodes\nfor a user/network pick the first one (as they should, when\nthings are healthy), the inter-cluster routing is minimal\nto zero.", + "type": "array", + "items": { + "$ref": "#/definitions/tailcfg.DERPNode" + } + }, + "regionCode": { + "description": "RegionCode is a short name for the region. It's usually a popular\ncity or airport code in the region: \"nyc\", \"sf\", \"sin\",\n\"fra\", etc.", + "type": "string" + }, + "regionID": { + "description": "RegionID is a unique integer for a geographic region.\n\nIt corresponds to the legacy derpN.tailscale.com hostnames\nused by older clients. (Older clients will continue to resolve\nderpN.tailscale.com when contacting peers, rather than use\nthe server-provided DERPMap)\n\nRegionIDs must be non-zero, positive, and guaranteed to fit\nin a JavaScript number.\n\nRegionIDs in range 900-999 are reserved for end users to run their\nown DERP nodes.", + "type": "integer" + }, + "regionName": { + "description": "RegionName is a long English name for the region: \"New York City\",\n\"San Francisco\", \"Singapore\", \"Frankfurt\", etc.", + "type": "string" + } + } } }, "securityDefinitions": { diff --git a/coderd/workspaceagents.go b/coderd/workspaceagents.go index 649d1849df2c9..3330559e6d132 100644 --- a/coderd/workspaceagents.go +++ b/coderd/workspaceagents.go @@ -65,6 +65,14 @@ func (api *API) workspaceAgent(rw http.ResponseWriter, r *http.Request) { httpapi.Write(ctx, rw, http.StatusOK, apiAgent) } +// @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 +// @Router /workspaceagents/me/metadata [get] func (api *API) workspaceAgentMetadata(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() workspaceAgent := httpmw.WorkspaceAgent(r) diff --git a/coderd/workspaceresourceauth.go b/coderd/workspaceresourceauth.go index 396d324ff6389..ea72b794ada37 100644 --- a/coderd/workspaceresourceauth.go +++ b/coderd/workspaceresourceauth.go @@ -24,7 +24,7 @@ import ( // @ID authenticate-agent-on-azure-instance // @Security CoderSessionToken // @Produce json -// @Tags Workspaces +// @Tags Agents // @Param request body codersdk.AzureInstanceIdentityToken true "Instance identity token" // @Success 200 {object} codersdk.WorkspaceAgentAuthenticateResponse // @Router /workspaceagents/azure-instance-identity [post] @@ -53,7 +53,7 @@ func (api *API) postWorkspaceAuthAzureInstanceIdentity(rw http.ResponseWriter, r // @ID authenticate-agent-on-aws-instance // @Security CoderSessionToken // @Produce json -// @Tags Workspaces +// @Tags Agents // @Param request body codersdk.AWSInstanceIdentityToken true "Instance identity token" // @Success 200 {object} codersdk.WorkspaceAgentAuthenticateResponse // @Router /workspaceagents/aws-instance-identity [post] @@ -82,7 +82,7 @@ func (api *API) postWorkspaceAuthAWSInstanceIdentity(rw http.ResponseWriter, r * // @ID authenticate-agent-on-google-cloud-instance // @Security CoderSessionToken // @Produce json -// @Tags Workspaces +// @Tags Agents // @Param request body codersdk.GoogleInstanceIdentityToken true "Instance identity token" // @Success 200 {object} codersdk.WorkspaceAgentAuthenticateResponse // @Router /workspaceagents/google-instance-identity [post] diff --git a/codersdk/workspaceagents.go b/codersdk/workspaceagents.go index 258b108737b9c..cd4c237616607 100644 --- a/codersdk/workspaceagents.go +++ b/codersdk/workspaceagents.go @@ -35,15 +35,15 @@ const ( ) type WorkspaceAgent struct { - ID uuid.UUID `json:"id"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` - FirstConnectedAt *time.Time `json:"first_connected_at,omitempty"` - LastConnectedAt *time.Time `json:"last_connected_at,omitempty"` - DisconnectedAt *time.Time `json:"disconnected_at,omitempty"` - Status WorkspaceAgentStatus `json:"status"` + ID uuid.UUID `json:"id" format:"uuid"` + CreatedAt time.Time `json:"created_at" format:"date-time"` + UpdatedAt time.Time `json:"updated_at" format:"date-time"` + FirstConnectedAt *time.Time `json:"first_connected_at,omitempty" format:"date-time"` + LastConnectedAt *time.Time `json:"last_connected_at,omitempty" format:"date-time"` + DisconnectedAt *time.Time `json:"disconnected_at,omitempty" format:"date-time"` + Status WorkspaceAgentStatus `json:"status" enums:"connecting,connected,disconnected,timeout"` Name string `json:"name"` - ResourceID uuid.UUID `json:"resource_id"` + ResourceID uuid.UUID `json:"resource_id" format:"uuid"` InstanceID string `json:"instance_id,omitempty"` Architecture string `json:"architecture"` EnvironmentVariables map[string]string `json:"environment_variables"` diff --git a/codersdk/workspaceapps.go b/codersdk/workspaceapps.go index 8f6003b5fae48..a8bcb31b792d7 100644 --- a/codersdk/workspaceapps.go +++ b/codersdk/workspaceapps.go @@ -22,7 +22,7 @@ const ( ) type WorkspaceApp struct { - ID uuid.UUID `json:"id"` + ID uuid.UUID `json:"id" format:"uuid"` // URL is the address being proxied to inside the workspace. // If external is specified, this will be opened on the client. URL string `json:"url"` @@ -42,7 +42,7 @@ type WorkspaceApp struct { // and there is no app wildcard configured on the server, the app will not // be accessible in the UI. Subdomain bool `json:"subdomain"` - SharingLevel WorkspaceAppSharingLevel `json:"sharing_level"` + SharingLevel WorkspaceAppSharingLevel `json:"sharing_level" enums:"owner,authenticated,public"` // Healthcheck specifies the configuration for checking app health. Healthcheck Healthcheck `json:"healthcheck"` Health WorkspaceAppHealth `json:"health"` diff --git a/docs/api/agents.md b/docs/api/agents.md new file mode 100644 index 0000000000000..f04a8a5ff15ef --- /dev/null +++ b/docs/api/agents.md @@ -0,0 +1,252 @@ +# Agents + +> This page is incomplete, stay tuned. + +## Authenticate agent on AWS instance + +### Code samples + +```shell +# Example request using curl +curl -X POST http://coder-server:8080/api/v2/workspaceagents/aws-instance-identity \ + -H 'Content-Type: application/json' \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`POST /workspaceagents/aws-instance-identity` + +> Body parameter + +```json +{ + "document": "string", + "signature": "string" +} +``` + +### Parameters + +| Name | In | Type | Required | Description | +| ------ | ---- | -------------------------------------------------------------------------------- | -------- | ----------------------- | +| `body` | body | [codersdk.AWSInstanceIdentityToken](schemas.md#codersdkawsinstanceidentitytoken) | true | Instance identity token | + +### Example responses + +> 200 Response + +```json +{ + "session_token": "string" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ---------------------------------------------------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.WorkspaceAgentAuthenticateResponse](schemas.md#codersdkworkspaceagentauthenticateresponse) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Authenticate agent on Azure instance + +### Code samples + +```shell +# Example request using curl +curl -X POST http://coder-server:8080/api/v2/workspaceagents/azure-instance-identity \ + -H 'Content-Type: application/json' \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`POST /workspaceagents/azure-instance-identity` + +> Body parameter + +```json +{ + "encoding": "string", + "signature": "string" +} +``` + +### Parameters + +| Name | In | Type | Required | Description | +| ------ | ---- | ------------------------------------------------------------------------------------ | -------- | ----------------------- | +| `body` | body | [codersdk.AzureInstanceIdentityToken](schemas.md#codersdkazureinstanceidentitytoken) | true | Instance identity token | + +### Example responses + +> 200 Response + +```json +{ + "session_token": "string" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ---------------------------------------------------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.WorkspaceAgentAuthenticateResponse](schemas.md#codersdkworkspaceagentauthenticateresponse) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Authenticate agent on Google Cloud instance + +### Code samples + +```shell +# Example request using curl +curl -X POST http://coder-server:8080/api/v2/workspaceagents/google-instance-identity \ + -H 'Content-Type: application/json' \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`POST /workspaceagents/google-instance-identity` + +> Body parameter + +```json +{ + "json_web_token": "string" +} +``` + +### Parameters + +| Name | In | Type | Required | Description | +| ------ | ---- | -------------------------------------------------------------------------------------- | -------- | ----------------------- | +| `body` | body | [codersdk.GoogleInstanceIdentityToken](schemas.md#codersdkgoogleinstanceidentitytoken) | true | Instance identity token | + +### Example responses + +> 200 Response + +```json +{ + "session_token": "string" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ---------------------------------------------------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.WorkspaceAgentAuthenticateResponse](schemas.md#codersdkworkspaceagentauthenticateresponse) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Get authorized workspace agent metadata + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/workspaceagents/me/metadata \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /workspaceagents/me/metadata` + +### Example responses + +> 200 Response + +```json +{ + "apps": [ + { + "command": "string", + "display_name": "string", + "external": true, + "health": "string", + "healthcheck": { + "interval": 0, + "threshold": 0, + "url": "string" + }, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "sharing_level": "owner", + "slug": "string", + "subdomain": true, + "url": "string" + } + ], + "derpmap": { + "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" + } + } + }, + "directory": "string", + "environment_variables": { + "property1": "string", + "property2": "string" + }, + "git_auth_configs": 0, + "motd_file": "string", + "startup_script": "string", + "vscode_port_proxy_uri": "string" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ---------------------------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.WorkspaceAgentMetadata](schemas.md#codersdkworkspaceagentmetadata) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. diff --git a/docs/api/schemas.md b/docs/api/schemas.md index f7bf566b09612..d01652d468e97 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -2960,8 +2960,8 @@ Parameter represents a set value for the scope. "url": "string" }, "icon": "string", - "id": "string", - "sharing_level": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "sharing_level": "owner", "slug": "string", "subdomain": true, "url": "string" @@ -2969,17 +2969,17 @@ Parameter represents a set value for the scope. ], "architecture": "string", "connection_timeout_seconds": 0, - "created_at": "string", + "created_at": "2019-08-24T14:15:22Z", "directory": "string", - "disconnected_at": "string", + "disconnected_at": "2019-08-24T14:15:22Z", "environment_variables": { "property1": "string", "property2": "string" }, - "first_connected_at": "string", - "id": "string", + "first_connected_at": "2019-08-24T14:15:22Z", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "instance_id": "string", - "last_connected_at": "string", + "last_connected_at": "2019-08-24T14:15:22Z", "latency": { "property1": { "latency_ms": 0, @@ -2992,11 +2992,11 @@ Parameter represents a set value for the scope. }, "name": "string", "operating_system": "string", - "resource_id": "string", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", "startup_script": "string", - "status": "string", + "status": "connecting", "troubleshooting_url": "string", - "updated_at": "string", + "updated_at": "2019-08-24T14:15:22Z", "version": "string" } ], @@ -3079,8 +3079,8 @@ Parameter represents a set value for the scope. "url": "string" }, "icon": "string", - "id": "string", - "sharing_level": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "sharing_level": "owner", "slug": "string", "subdomain": true, "url": "string" @@ -3088,17 +3088,17 @@ Parameter represents a set value for the scope. ], "architecture": "string", "connection_timeout_seconds": 0, - "created_at": "string", + "created_at": "2019-08-24T14:15:22Z", "directory": "string", - "disconnected_at": "string", + "disconnected_at": "2019-08-24T14:15:22Z", "environment_variables": { "property1": "string", "property2": "string" }, - "first_connected_at": "string", - "id": "string", + "first_connected_at": "2019-08-24T14:15:22Z", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "instance_id": "string", - "last_connected_at": "string", + "last_connected_at": "2019-08-24T14:15:22Z", "latency": { "property1": { "latency_ms": 0, @@ -3111,11 +3111,11 @@ Parameter represents a set value for the scope. }, "name": "string", "operating_system": "string", - "resource_id": "string", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", "startup_script": "string", - "status": "string", + "status": "connecting", "troubleshooting_url": "string", - "updated_at": "string", + "updated_at": "2019-08-24T14:15:22Z", "version": "string" } ``` @@ -3147,6 +3147,15 @@ Parameter represents a set value for the scope. | `updated_at` | string | false | | | | `version` | string | false | | | +#### Enumerated Values + +| Property | Value | +| -------- | -------------- | +| `status` | `connecting` | +| `status` | `connected` | +| `status` | `disconnected` | +| `status` | `timeout` | + ## codersdk.WorkspaceAgentAuthenticateResponse ```json @@ -3161,6 +3170,106 @@ Parameter represents a set value for the scope. | --------------- | ------ | -------- | ------------ | ----------- | | `session_token` | string | false | | | +## codersdk.WorkspaceAgentMetadata + +```json +{ + "apps": [ + { + "command": "string", + "display_name": "string", + "external": true, + "health": "string", + "healthcheck": { + "interval": 0, + "threshold": 0, + "url": "string" + }, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "sharing_level": "owner", + "slug": "string", + "subdomain": true, + "url": "string" + } + ], + "derpmap": { + "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" + } + } + }, + "directory": "string", + "environment_variables": { + "property1": "string", + "property2": "string" + }, + "git_auth_configs": 0, + "motd_file": "string", + "startup_script": "string", + "vscode_port_proxy_uri": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ----------------------- | ------------------------------------------------------- | -------- | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `apps` | array of [codersdk.WorkspaceApp](#codersdkworkspaceapp) | false | | | +| `derpmap` | [tailcfg.DERPMap](#tailcfgderpmap) | false | | | +| `directory` | string | false | | | +| `environment_variables` | object | false | | | +| » `[any property]` | string | false | | | +| `git_auth_configs` | integer | false | | Git auth configs stores the number of Git configurations the Coder deployment has. If this number is >0, we set up special configuration in the workspace. | +| `motd_file` | string | false | | | +| `startup_script` | string | false | | | +| `vscode_port_proxy_uri` | string | false | | | + ## codersdk.WorkspaceApp ```json @@ -3175,8 +3284,8 @@ Parameter represents a set value for the scope. "url": "string" }, "icon": "string", - "id": "string", - "sharing_level": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "sharing_level": "owner", "slug": "string", "subdomain": true, "url": "string" @@ -3199,6 +3308,14 @@ Parameter represents a set value for the scope. | `subdomain` | boolean | false | | Subdomain denotes whether the app should be accessed via a path on the `coder server` or via a hostname-based dev URL. If this is set to true and there is no app wildcard configured on the server, the app will not be accessible in the UI. | | `url` | string | false | | URL is the address being proxied to inside the workspace. If external is specified, this will be opened on the client. | +#### Enumerated Values + +| Property | Value | +| --------------- | --------------- | +| `sharing_level` | `owner` | +| `sharing_level` | `authenticated` | +| `sharing_level` | `public` | + ## codersdk.WorkspaceBuild ```json @@ -3242,8 +3359,8 @@ Parameter represents a set value for the scope. "url": "string" }, "icon": "string", - "id": "string", - "sharing_level": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "sharing_level": "owner", "slug": "string", "subdomain": true, "url": "string" @@ -3251,17 +3368,17 @@ Parameter represents a set value for the scope. ], "architecture": "string", "connection_timeout_seconds": 0, - "created_at": "string", + "created_at": "2019-08-24T14:15:22Z", "directory": "string", - "disconnected_at": "string", + "disconnected_at": "2019-08-24T14:15:22Z", "environment_variables": { "property1": "string", "property2": "string" }, - "first_connected_at": "string", - "id": "string", + "first_connected_at": "2019-08-24T14:15:22Z", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "instance_id": "string", - "last_connected_at": "string", + "last_connected_at": "2019-08-24T14:15:22Z", "latency": { "property1": { "latency_ms": 0, @@ -3274,11 +3391,11 @@ Parameter represents a set value for the scope. }, "name": "string", "operating_system": "string", - "resource_id": "string", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", "startup_script": "string", - "status": "string", + "status": "connecting", "troubleshooting_url": "string", - "updated_at": "string", + "updated_at": "2019-08-24T14:15:22Z", "version": "string" } ], @@ -3375,8 +3492,8 @@ Parameter represents a set value for the scope. "url": "string" }, "icon": "string", - "id": "string", - "sharing_level": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "sharing_level": "owner", "slug": "string", "subdomain": true, "url": "string" @@ -3384,17 +3501,17 @@ Parameter represents a set value for the scope. ], "architecture": "string", "connection_timeout_seconds": 0, - "created_at": "string", + "created_at": "2019-08-24T14:15:22Z", "directory": "string", - "disconnected_at": "string", + "disconnected_at": "2019-08-24T14:15:22Z", "environment_variables": { "property1": "string", "property2": "string" }, - "first_connected_at": "string", - "id": "string", + "first_connected_at": "2019-08-24T14:15:22Z", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "instance_id": "string", - "last_connected_at": "string", + "last_connected_at": "2019-08-24T14:15:22Z", "latency": { "property1": { "latency_ms": 0, @@ -3407,11 +3524,11 @@ Parameter represents a set value for the scope. }, "name": "string", "operating_system": "string", - "resource_id": "string", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", "startup_script": "string", - "status": "string", + "status": "connecting", "troubleshooting_url": "string", - "updated_at": "string", + "updated_at": "2019-08-24T14:15:22Z", "version": "string" } ], @@ -3523,8 +3640,8 @@ Parameter represents a set value for the scope. "health": "string", "healthcheck": {}, "icon": "string", - "id": "string", - "sharing_level": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "sharing_level": "owner", "slug": "string", "subdomain": true, "url": "string" @@ -3532,17 +3649,17 @@ Parameter represents a set value for the scope. ], "architecture": "string", "connection_timeout_seconds": 0, - "created_at": "string", + "created_at": "2019-08-24T14:15:22Z", "directory": "string", - "disconnected_at": "string", + "disconnected_at": "2019-08-24T14:15:22Z", "environment_variables": { "property1": "string", "property2": "string" }, - "first_connected_at": "string", - "id": "string", + "first_connected_at": "2019-08-24T14:15:22Z", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "instance_id": "string", - "last_connected_at": "string", + "last_connected_at": "2019-08-24T14:15:22Z", "latency": { "property1": { "latency_ms": 0, @@ -3555,11 +3672,11 @@ Parameter represents a set value for the scope. }, "name": "string", "operating_system": "string", - "resource_id": "string", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", "startup_script": "string", - "status": "string", + "status": "connecting", "troubleshooting_url": "string", - "updated_at": "string", + "updated_at": "2019-08-24T14:15:22Z", "version": "string" } ], @@ -3623,3 +3740,152 @@ Parameter represents a set value for the scope. ### Properties _None_ + +## tailcfg.DERPMap + +```json +{ + "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 | +| -------------------- | ------- | -------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `omitDefaultRegions` | boolean | false | | Omitdefaultregions specifies to not use Tailscale's DERP servers, and only use those specified in this DERPMap. If there are none set outside of the defaults, this is a noop. | +| `regions` | object | false | | Regions is the set of geographic regions running DERP node(s). | + +It's keyed by the DERPRegion.RegionID. +The numbers are not necessarily contiguous.| +|» `[any property]`|[tailcfg.DERPRegion](#tailcfgderpregion)|false||| + +## tailcfg.DERPNode + +```json +{ + "certName": "string", + "derpport": 0, + "forceHTTP": true, + "hostName": "string", + "insecureForTests": true, + "ipv4": "string", + "ipv6": "string", + "name": "string", + "regionID": 0, + "stunonly": true, + "stunport": 0, + "stuntestIP": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| --------------------------------------------------------------------------------------------------------------------- | ------- | -------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `certName` | string | false | | Certname optionally specifies the expected TLS cert common name. If empty, HostName is used. If CertName is non-empty, HostName is only used for the TCP dial (if IPv4/IPv6 are not present) + TLS ClientHello. | +| `derpport` | integer | false | | Derpport optionally provides an alternate TLS port number for the DERP HTTPS server. | +| If zero, 443 is used. | +| `forceHTTP` | boolean | false | | Forcehttp is used by unit tests to force HTTP. It should not be set by users. | +| `hostName` | string | false | | Hostname is the DERP node's hostname. | +| It is required but need not be unique; multiple nodes may have the same HostName but vary in configuration otherwise. | +| `insecureForTests` | boolean | false | | Insecurefortests is used by unit tests to disable TLS verification. It should not be set by users. | +| `ipv4` | string | false | | Ipv4 optionally forces an IPv4 address to use, instead of using DNS. If empty, A record(s) from DNS lookups of HostName are used. If the string is not an IPv4 address, IPv4 is not used; the conventional string to disable IPv4 (and not use DNS) is "none". | +| `ipv6` | string | false | | Ipv6 optionally forces an IPv6 address to use, instead of using DNS. If empty, AAAA record(s) from DNS lookups of HostName are used. If the string is not an IPv6 address, IPv6 is not used; the conventional string to disable IPv6 (and not use DNS) is "none". | +| `name` | string | false | | Name is a unique node name (across all regions). It is not a host name. It's typically of the form "1b", "2a", "3b", etc. (region ID + suffix within that region) | +| `regionID` | integer | false | | Regionid is the RegionID of the DERPRegion that this node is running in. | +| `stunonly` | boolean | false | | Stunonly marks a node as only a STUN server and not a DERP server. | +| `stunport` | integer | false | | Port optionally specifies a STUN port to use. Zero means 3478. To disable STUN on this node, use -1. | +| `stuntestIP` | string | false | | Stuntestip is used in tests to override the STUN server's IP. If empty, it's assumed to be the same as the DERP server. | + +## tailcfg.DERPRegion + +```json +{ + "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 | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | -------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `avoid` | boolean | false | | Avoid is whether the client should avoid picking this as its home region. The region should only be used if a peer is there. Clients already using this region as their home should migrate away to a new region without Avoid set. | +| `embeddedRelay` | boolean | false | | Embeddedrelay is true when the region is bundled with the Coder control plane. | +| `nodes` | array of [tailcfg.DERPNode](#tailcfgderpnode) | false | | Nodes are the DERP nodes running in this region, in priority order for the current client. Client TLS connections should ideally only go to the first entry (falling back to the second if necessary). STUN packets should go to the first 1 or 2. | +| If nodes within a region route packets amongst themselves, but not to other regions. That said, each user/domain should get a the same preferred node order, so if all nodes for a user/network pick the first one (as they should, when things are healthy), the inter-cluster routing is minimal to zero. | +| `regionCode` | string | false | | Regioncode is a short name for the region. It's usually a popular city or airport code in the region: "nyc", "sf", "sin", "fra", etc. | +| `regionID` | integer | false | | Regionid is a unique integer for a geographic region. | + +It corresponds to the legacy derpN.tailscale.com hostnames used by older clients. (Older clients will continue to resolve derpN.tailscale.com when contacting peers, rather than use the server-provided DERPMap) +RegionIDs must be non-zero, positive, and guaranteed to fit in a JavaScript number. +RegionIDs in range 900-999 are reserved for end users to run their own DERP nodes.| +|`regionName`|string|false||Regionname is a long English name for the region: "New York City", "San Francisco", "Singapore", "Frankfurt", etc.| diff --git a/docs/api/workspaces.md b/docs/api/workspaces.md index 2e0ae40e7ff9e..288465fcab3e5 100644 --- a/docs/api/workspaces.md +++ b/docs/api/workspaces.md @@ -72,8 +72,8 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/member "url": "string" }, "icon": "string", - "id": "string", - "sharing_level": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "sharing_level": "owner", "slug": "string", "subdomain": true, "url": "string" @@ -81,17 +81,17 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/member ], "architecture": "string", "connection_timeout_seconds": 0, - "created_at": "string", + "created_at": "2019-08-24T14:15:22Z", "directory": "string", - "disconnected_at": "string", + "disconnected_at": "2019-08-24T14:15:22Z", "environment_variables": { "property1": "string", "property2": "string" }, - "first_connected_at": "string", - "id": "string", + "first_connected_at": "2019-08-24T14:15:22Z", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "instance_id": "string", - "last_connected_at": "string", + "last_connected_at": "2019-08-24T14:15:22Z", "latency": { "property1": { "latency_ms": 0, @@ -104,11 +104,11 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/member }, "name": "string", "operating_system": "string", - "resource_id": "string", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", "startup_script": "string", - "status": "string", + "status": "connecting", "troubleshooting_url": "string", - "updated_at": "string", + "updated_at": "2019-08-24T14:15:22Z", "version": "string" } ], @@ -233,8 +233,8 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/workspace/{workspacenam "url": "string" }, "icon": "string", - "id": "string", - "sharing_level": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "sharing_level": "owner", "slug": "string", "subdomain": true, "url": "string" @@ -242,17 +242,17 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/workspace/{workspacenam ], "architecture": "string", "connection_timeout_seconds": 0, - "created_at": "string", + "created_at": "2019-08-24T14:15:22Z", "directory": "string", - "disconnected_at": "string", + "disconnected_at": "2019-08-24T14:15:22Z", "environment_variables": { "property1": "string", "property2": "string" }, - "first_connected_at": "string", - "id": "string", + "first_connected_at": "2019-08-24T14:15:22Z", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "instance_id": "string", - "last_connected_at": "string", + "last_connected_at": "2019-08-24T14:15:22Z", "latency": { "property1": { "latency_ms": 0, @@ -265,11 +265,11 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/workspace/{workspacenam }, "name": "string", "operating_system": "string", - "resource_id": "string", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", "startup_script": "string", - "status": "string", + "status": "connecting", "troubleshooting_url": "string", - "updated_at": "string", + "updated_at": "2019-08-24T14:15:22Z", "version": "string" } ], @@ -323,146 +323,6 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/workspace/{workspacenam To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. -## Authenticate agent on AWS instance - -### Code samples - -```shell -# Example request using curl -curl -X POST http://coder-server:8080/api/v2/workspaceagents/aws-instance-identity \ - -H 'Content-Type: application/json' \ - -H 'Accept: application/json' \ - -H 'Coder-Session-Token: API_KEY' -``` - -`POST /workspaceagents/aws-instance-identity` - -> Body parameter - -```json -{ - "document": "string", - "signature": "string" -} -``` - -### Parameters - -| Name | In | Type | Required | Description | -| ------ | ---- | -------------------------------------------------------------------------------- | -------- | ----------------------- | -| `body` | body | [codersdk.AWSInstanceIdentityToken](schemas.md#codersdkawsinstanceidentitytoken) | true | Instance identity token | - -### Example responses - -> 200 Response - -```json -{ - "session_token": "string" -} -``` - -### Responses - -| Status | Meaning | Description | Schema | -| ------ | ------------------------------------------------------- | ----------- | ---------------------------------------------------------------------------------------------------- | -| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.WorkspaceAgentAuthenticateResponse](schemas.md#codersdkworkspaceagentauthenticateresponse) | - -To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. - -## Authenticate agent on Azure instance - -### Code samples - -```shell -# Example request using curl -curl -X POST http://coder-server:8080/api/v2/workspaceagents/azure-instance-identity \ - -H 'Content-Type: application/json' \ - -H 'Accept: application/json' \ - -H 'Coder-Session-Token: API_KEY' -``` - -`POST /workspaceagents/azure-instance-identity` - -> Body parameter - -```json -{ - "encoding": "string", - "signature": "string" -} -``` - -### Parameters - -| Name | In | Type | Required | Description | -| ------ | ---- | ------------------------------------------------------------------------------------ | -------- | ----------------------- | -| `body` | body | [codersdk.AzureInstanceIdentityToken](schemas.md#codersdkazureinstanceidentitytoken) | true | Instance identity token | - -### Example responses - -> 200 Response - -```json -{ - "session_token": "string" -} -``` - -### Responses - -| Status | Meaning | Description | Schema | -| ------ | ------------------------------------------------------- | ----------- | ---------------------------------------------------------------------------------------------------- | -| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.WorkspaceAgentAuthenticateResponse](schemas.md#codersdkworkspaceagentauthenticateresponse) | - -To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. - -## Authenticate agent on Google Cloud instance - -### Code samples - -```shell -# Example request using curl -curl -X POST http://coder-server:8080/api/v2/workspaceagents/google-instance-identity \ - -H 'Content-Type: application/json' \ - -H 'Accept: application/json' \ - -H 'Coder-Session-Token: API_KEY' -``` - -`POST /workspaceagents/google-instance-identity` - -> Body parameter - -```json -{ - "json_web_token": "string" -} -``` - -### Parameters - -| Name | In | Type | Required | Description | -| ------ | ---- | -------------------------------------------------------------------------------------- | -------- | ----------------------- | -| `body` | body | [codersdk.GoogleInstanceIdentityToken](schemas.md#codersdkgoogleinstanceidentitytoken) | true | Instance identity token | - -### Example responses - -> 200 Response - -```json -{ - "session_token": "string" -} -``` - -### Responses - -| Status | Meaning | Description | Schema | -| ------ | ------------------------------------------------------- | ----------- | ---------------------------------------------------------------------------------------------------- | -| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.WorkspaceAgentAuthenticateResponse](schemas.md#codersdkworkspaceagentauthenticateresponse) | - -To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. - ## Get workspace build ### Code samples @@ -527,8 +387,8 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild} \ "url": "string" }, "icon": "string", - "id": "string", - "sharing_level": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "sharing_level": "owner", "slug": "string", "subdomain": true, "url": "string" @@ -536,17 +396,17 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild} \ ], "architecture": "string", "connection_timeout_seconds": 0, - "created_at": "string", + "created_at": "2019-08-24T14:15:22Z", "directory": "string", - "disconnected_at": "string", + "disconnected_at": "2019-08-24T14:15:22Z", "environment_variables": { "property1": "string", "property2": "string" }, - "first_connected_at": "string", - "id": "string", + "first_connected_at": "2019-08-24T14:15:22Z", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "instance_id": "string", - "last_connected_at": "string", + "last_connected_at": "2019-08-24T14:15:22Z", "latency": { "property1": { "latency_ms": 0, @@ -559,11 +419,11 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild} \ }, "name": "string", "operating_system": "string", - "resource_id": "string", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", "startup_script": "string", - "status": "string", + "status": "connecting", "troubleshooting_url": "string", - "updated_at": "string", + "updated_at": "2019-08-24T14:15:22Z", "version": "string" } ], @@ -760,8 +620,8 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/res "url": "string" }, "icon": "string", - "id": "string", - "sharing_level": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "sharing_level": "owner", "slug": "string", "subdomain": true, "url": "string" @@ -769,17 +629,17 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/res ], "architecture": "string", "connection_timeout_seconds": 0, - "created_at": "string", + "created_at": "2019-08-24T14:15:22Z", "directory": "string", - "disconnected_at": "string", + "disconnected_at": "2019-08-24T14:15:22Z", "environment_variables": { "property1": "string", "property2": "string" }, - "first_connected_at": "string", - "id": "string", + "first_connected_at": "2019-08-24T14:15:22Z", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "instance_id": "string", - "last_connected_at": "string", + "last_connected_at": "2019-08-24T14:15:22Z", "latency": { "property1": { "latency_ms": 0, @@ -792,11 +652,11 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/res }, "name": "string", "operating_system": "string", - "resource_id": "string", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", "startup_script": "string", - "status": "string", + "status": "connecting", "troubleshooting_url": "string", - "updated_at": "string", + "updated_at": "2019-08-24T14:15:22Z", "version": "string" } ], @@ -888,11 +748,18 @@ Status Code **200** #### Enumerated Values -| Property | Value | -| ---------------------- | -------- | -| `workspace_transition` | `start` | -| `workspace_transition` | `stop` | -| `workspace_transition` | `delete` | +| Property | Value | +| ---------------------- | --------------- | +| `sharing_level` | `owner` | +| `sharing_level` | `authenticated` | +| `sharing_level` | `public` | +| `status` | `connecting` | +| `status` | `connected` | +| `status` | `disconnected` | +| `status` | `timeout` | +| `workspace_transition` | `start` | +| `workspace_transition` | `stop` | +| `workspace_transition` | `delete` | To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. @@ -960,8 +827,8 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/sta "url": "string" }, "icon": "string", - "id": "string", - "sharing_level": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "sharing_level": "owner", "slug": "string", "subdomain": true, "url": "string" @@ -969,17 +836,17 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/sta ], "architecture": "string", "connection_timeout_seconds": 0, - "created_at": "string", + "created_at": "2019-08-24T14:15:22Z", "directory": "string", - "disconnected_at": "string", + "disconnected_at": "2019-08-24T14:15:22Z", "environment_variables": { "property1": "string", "property2": "string" }, - "first_connected_at": "string", - "id": "string", + "first_connected_at": "2019-08-24T14:15:22Z", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "instance_id": "string", - "last_connected_at": "string", + "last_connected_at": "2019-08-24T14:15:22Z", "latency": { "property1": { "latency_ms": 0, @@ -992,11 +859,11 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/sta }, "name": "string", "operating_system": "string", - "resource_id": "string", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", "startup_script": "string", - "status": "string", + "status": "connecting", "troubleshooting_url": "string", - "updated_at": "string", + "updated_at": "2019-08-24T14:15:22Z", "version": "string" } ], @@ -1128,8 +995,8 @@ curl -X GET http://coder-server:8080/api/v2/workspaces \ "health": "string", "healthcheck": {}, "icon": "string", - "id": "string", - "sharing_level": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "sharing_level": "owner", "slug": "string", "subdomain": true, "url": "string" @@ -1137,17 +1004,17 @@ curl -X GET http://coder-server:8080/api/v2/workspaces \ ], "architecture": "string", "connection_timeout_seconds": 0, - "created_at": "string", + "created_at": "2019-08-24T14:15:22Z", "directory": "string", - "disconnected_at": "string", + "disconnected_at": "2019-08-24T14:15:22Z", "environment_variables": { "property1": "string", "property2": "string" }, - "first_connected_at": "string", - "id": "string", + "first_connected_at": "2019-08-24T14:15:22Z", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "instance_id": "string", - "last_connected_at": "string", + "last_connected_at": "2019-08-24T14:15:22Z", "latency": { "property1": { "latency_ms": 0, @@ -1160,11 +1027,11 @@ curl -X GET http://coder-server:8080/api/v2/workspaces \ }, "name": "string", "operating_system": "string", - "resource_id": "string", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", "startup_script": "string", - "status": "string", + "status": "connecting", "troubleshooting_url": "string", - "updated_at": "string", + "updated_at": "2019-08-24T14:15:22Z", "version": "string" } ], @@ -1290,8 +1157,8 @@ curl -X GET http://coder-server:8080/api/v2/workspaces/{id} \ "url": "string" }, "icon": "string", - "id": "string", - "sharing_level": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "sharing_level": "owner", "slug": "string", "subdomain": true, "url": "string" @@ -1299,17 +1166,17 @@ curl -X GET http://coder-server:8080/api/v2/workspaces/{id} \ ], "architecture": "string", "connection_timeout_seconds": 0, - "created_at": "string", + "created_at": "2019-08-24T14:15:22Z", "directory": "string", - "disconnected_at": "string", + "disconnected_at": "2019-08-24T14:15:22Z", "environment_variables": { "property1": "string", "property2": "string" }, - "first_connected_at": "string", - "id": "string", + "first_connected_at": "2019-08-24T14:15:22Z", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "instance_id": "string", - "last_connected_at": "string", + "last_connected_at": "2019-08-24T14:15:22Z", "latency": { "property1": { "latency_ms": 0, @@ -1322,11 +1189,11 @@ curl -X GET http://coder-server:8080/api/v2/workspaces/{id} \ }, "name": "string", "operating_system": "string", - "resource_id": "string", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", "startup_script": "string", - "status": "string", + "status": "connecting", "troubleshooting_url": "string", - "updated_at": "string", + "updated_at": "2019-08-24T14:15:22Z", "version": "string" } ], diff --git a/docs/manifest.json b/docs/manifest.json index 5e20465ae272e..ee27d96a9c510 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -361,6 +361,10 @@ "title": "Parameters", "path": "./api/parameters.md" }, + { + "title": "Agents", + "path": "./api/agents.md" + }, { "title": "Schemas", "path": "./api/schemas.md" From 67a85b93f42d4aeefcb7f01c7ade6699db773f44 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Mon, 2 Jan 2023 16:10:29 +0100 Subject: [PATCH 06/36] workspaceagents.go in progress --- coderd/apidoc/docs.go | 221 +++++++++++++++++++++++++++++++++++++ coderd/apidoc/swagger.json | 203 ++++++++++++++++++++++++++++++++++ coderd/workspaceagents.go | 37 ++++++- docs/api/agents.md | 167 ++++++++++++++++++++++++++++ docs/api/schemas.md | 92 +++++++++++++++ 5 files changed, 719 insertions(+), 1 deletion(-) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index b8180c96821b4..939d03ef63286 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -983,6 +983,83 @@ const docTemplate = `{ } } }, + "/workspaceagents/me/app-health": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Agents" + ], + "summary": "Submit workspace application health", + "operationId": "submit-workspace-workspace-agent-health", + "parameters": [ + { + "description": "Application health request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.PostWorkspaceAppHealthsRequest" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/workspaceagents/me/gitauth": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Agents" + ], + "summary": "Get workspace agent Git auth", + "operationId": "get-workspace-agent-git-auth", + "parameters": [ + { + "type": "string", + "format": "uri", + "description": "Git URL", + "name": "url", + "in": "query", + "required": true + }, + { + "type": "boolean", + "description": "Wait for a new token to be issued", + "name": "listen", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceAgentGitAuthResponse" + } + } + } + } + }, "/workspaceagents/me/metadata": { "get": { "security": [ @@ -1011,6 +1088,75 @@ const docTemplate = `{ } } }, + "/workspaceagents/me/report-stats": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Agents" + ], + "summary": "Submit workspace agent stats", + "operationId": "submit-workspace-workspace-agent-stats", + "parameters": [ + { + "description": "Stats request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.AgentStats" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.AgentStatsResponse" + } + } + } + } + }, + "/workspaceagents/me/version": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Agents" + ], + "summary": "Submit workspace agent version", + "operationId": "submit-workspace-workspace-agent-version", + "parameters": [ + { + "description": "Version request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.PostWorkspaceAgentVersionRequest" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, "/workspacebuilds/{workspacebuild}": { "get": { "security": [ @@ -1560,6 +1706,47 @@ const docTemplate = `{ } } }, + "codersdk.AgentStats": { + "type": "object", + "properties": { + "conns_by_proto": { + "description": "ConnsByProto is a count of connections by protocol.", + "type": "object", + "additionalProperties": { + "type": "integer" + } + }, + "num_comms": { + "description": "NumConns is the number of connections received by an agent.", + "type": "integer" + }, + "rx_bytes": { + "description": "RxBytes is the number of received bytes.", + "type": "integer" + }, + "rx_packets": { + "description": "RxPackets is the number of received packets.", + "type": "integer" + }, + "tx_bytes": { + "description": "TxBytes is the number of transmitted bytes.", + "type": "integer" + }, + "tx_packets": { + "description": "TxPackets is the number of transmitted bytes.", + "type": "integer" + } + } + }, + "codersdk.AgentStatsResponse": { + "type": "object", + "properties": { + "report_interval": { + "description": "ReportInterval is the duration after which the agent should send stats\nagain.", + "type": "integer" + } + } + }, "codersdk.AuditDiff": { "type": "object", "additionalProperties": { @@ -2395,6 +2582,26 @@ const docTemplate = `{ } } }, + "codersdk.PostWorkspaceAgentVersionRequest": { + "type": "object", + "properties": { + "version": { + "type": "string" + } + } + }, + "codersdk.PostWorkspaceAppHealthsRequest": { + "type": "object", + "properties": { + "healths": { + "description": "Healths is a map of the workspace app name and the health of the app.", + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, "codersdk.PprofConfig": { "type": "object", "properties": { @@ -2975,6 +3182,20 @@ const docTemplate = `{ } } }, + "codersdk.WorkspaceAgentGitAuthResponse": { + "type": "object", + "properties": { + "password": { + "type": "string" + }, + "url": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, "codersdk.WorkspaceAgentMetadata": { "type": "object", "properties": { diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 4ddae97c7e83a..dd59178737b2f 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -853,6 +853,73 @@ } } }, + "/workspaceagents/me/app-health": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Agents"], + "summary": "Submit workspace application health", + "operationId": "submit-workspace-workspace-agent-health", + "parameters": [ + { + "description": "Application health request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.PostWorkspaceAppHealthsRequest" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/workspaceagents/me/gitauth": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Agents"], + "summary": "Get workspace agent Git auth", + "operationId": "get-workspace-agent-git-auth", + "parameters": [ + { + "type": "string", + "format": "uri", + "description": "Git URL", + "name": "url", + "in": "query", + "required": true + }, + { + "type": "boolean", + "description": "Wait for a new token to be issued", + "name": "listen", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceAgentGitAuthResponse" + } + } + } + } + }, "/workspaceagents/me/metadata": { "get": { "security": [ @@ -875,6 +942,67 @@ } } }, + "/workspaceagents/me/report-stats": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Agents"], + "summary": "Submit workspace agent stats", + "operationId": "submit-workspace-workspace-agent-stats", + "parameters": [ + { + "description": "Stats request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.AgentStats" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.AgentStatsResponse" + } + } + } + } + }, + "/workspaceagents/me/version": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Agents"], + "summary": "Submit workspace agent version", + "operationId": "submit-workspace-workspace-agent-version", + "parameters": [ + { + "description": "Version request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.PostWorkspaceAgentVersionRequest" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, "/workspacebuilds/{workspacebuild}": { "get": { "security": [ @@ -1360,6 +1488,47 @@ } } }, + "codersdk.AgentStats": { + "type": "object", + "properties": { + "conns_by_proto": { + "description": "ConnsByProto is a count of connections by protocol.", + "type": "object", + "additionalProperties": { + "type": "integer" + } + }, + "num_comms": { + "description": "NumConns is the number of connections received by an agent.", + "type": "integer" + }, + "rx_bytes": { + "description": "RxBytes is the number of received bytes.", + "type": "integer" + }, + "rx_packets": { + "description": "RxPackets is the number of received packets.", + "type": "integer" + }, + "tx_bytes": { + "description": "TxBytes is the number of transmitted bytes.", + "type": "integer" + }, + "tx_packets": { + "description": "TxPackets is the number of transmitted bytes.", + "type": "integer" + } + } + }, + "codersdk.AgentStatsResponse": { + "type": "object", + "properties": { + "report_interval": { + "description": "ReportInterval is the duration after which the agent should send stats\nagain.", + "type": "integer" + } + } + }, "codersdk.AuditDiff": { "type": "object", "additionalProperties": { @@ -2158,6 +2327,26 @@ } } }, + "codersdk.PostWorkspaceAgentVersionRequest": { + "type": "object", + "properties": { + "version": { + "type": "string" + } + } + }, + "codersdk.PostWorkspaceAppHealthsRequest": { + "type": "object", + "properties": { + "healths": { + "description": "Healths is a map of the workspace app name and the health of the app.", + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, "codersdk.PprofConfig": { "type": "object", "properties": { @@ -2717,6 +2906,20 @@ } } }, + "codersdk.WorkspaceAgentGitAuthResponse": { + "type": "object", + "properties": { + "password": { + "type": "string" + }, + "url": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, "codersdk.WorkspaceAgentMetadata": { "type": "object", "properties": { diff --git a/coderd/workspaceagents.go b/coderd/workspaceagents.go index 3330559e6d132..c6cd768f40f3a 100644 --- a/coderd/workspaceagents.go +++ b/coderd/workspaceagents.go @@ -148,6 +148,14 @@ func (api *API) workspaceAgentMetadata(rw http.ResponseWriter, r *http.Request) }) } +// @Summary Submit workspace agent version +// @ID submit-workspace-workspace-agent-version +// @Security CoderSessionToken +// @Produce application/json +// @Tags Agents +// @Param request body codersdk.PostWorkspaceAgentVersionRequest true "Version request" +// @Success 200 +// @Router /workspaceagents/me/version [post] func (api *API) postWorkspaceAgentVersion(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() workspaceAgent := httpmw.WorkspaceAgent(r) @@ -767,6 +775,14 @@ func convertWorkspaceAgent(derpMap *tailcfg.DERPMap, coordinator tailnet.Coordin return workspaceAgent, nil } +// @Summary Submit workspace agent stats +// @ID submit-workspace-workspace-agent-stats +// @Security CoderSessionToken +// @Produce application/json +// @Tags Agents +// @Param request body codersdk.AgentStats true "Stats request" +// @Success 200 {object} codersdk.AgentStatsResponse +// @Router /workspaceagents/me/report-stats [post] func (api *API) workspaceAgentReportStats(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() @@ -965,6 +981,14 @@ func (api *API) workspaceAgentReportStatsWebsocket(rw http.ResponseWriter, r *ht } } +// @Summary Submit workspace application health +// @ID submit-workspace-workspace-agent-health +// @Security CoderSessionToken +// @Produce application/json +// @Tags Agents +// @Param request body codersdk.PostWorkspaceAppHealthsRequest true "Application health request" +// @Success 200 +// @Router /workspaceagents/me/app-health [post] func (api *API) postWorkspaceAppHealth(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() workspaceAgent := httpmw.WorkspaceAgent(r) @@ -1080,7 +1104,18 @@ func (api *API) postWorkspaceAppHealth(rw http.ResponseWriter, r *http.Request) httpapi.Write(ctx, rw, http.StatusOK, nil) } -// postWorkspaceAgentsGitAuth returns a username and password for use +// @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) +// @Param listen query bool false "Wait for a new token to be issued" +// @Success 200 {object} codersdk.WorkspaceAgentGitAuthResponse +// @Router /workspaceagents/me/gitauth [get] +// +// workspaceAgentsGitAuth returns a username and password for use // with GIT_ASKPASS. func (api *API) workspaceAgentsGitAuth(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() diff --git a/docs/api/agents.md b/docs/api/agents.md index f04a8a5ff15ef..2f287e1903daf 100644 --- a/docs/api/agents.md +++ b/docs/api/agents.md @@ -142,6 +142,84 @@ curl -X POST http://coder-server:8080/api/v2/workspaceagents/google-instance-ide To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. +## Submit workspace application health + +### Code samples + +```shell +# Example request using curl +curl -X POST http://coder-server:8080/api/v2/workspaceagents/me/app-health \ + -H 'Content-Type: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`POST /workspaceagents/me/app-health` + +> Body parameter + +```json +{ + "healths": { + "property1": "string", + "property2": "string" + } +} +``` + +### Parameters + +| Name | In | Type | Required | Description | +| ------ | ---- | -------------------------------------------------------------------------------------------- | -------- | -------------------------- | +| `body` | body | [codersdk.PostWorkspaceAppHealthsRequest](schemas.md#codersdkpostworkspaceapphealthsrequest) | true | Application health request | + +### 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 by means of one of the following methods: **CoderSessionToken**. + +## Get workspace agent Git auth + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/workspaceagents/me/gitauth?url=http%3A%2F%2Fexample.com \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /workspaceagents/me/gitauth` + +### Parameters + +| Name | In | Type | Required | Description | +| -------- | ----- | ----------- | -------- | --------------------------------- | +| `url` | query | string(uri) | true | Git URL | +| `listen` | query | boolean | false | Wait for a new token to be issued | + +### Example responses + +> 200 Response + +```json +{ + "password": "string", + "url": "string", + "username": "string" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ------------------------------------------------------------------------------------------ | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.WorkspaceAgentGitAuthResponse](schemas.md#codersdkworkspaceagentgitauthresponse) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + ## Get authorized workspace agent metadata ### Code samples @@ -250,3 +328,92 @@ curl -X GET http://coder-server:8080/api/v2/workspaceagents/me/metadata \ | 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.WorkspaceAgentMetadata](schemas.md#codersdkworkspaceagentmetadata) | To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Submit workspace agent stats + +### Code samples + +```shell +# Example request using curl +curl -X POST http://coder-server:8080/api/v2/workspaceagents/me/report-stats \ + -H 'Content-Type: application/json' \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`POST /workspaceagents/me/report-stats` + +> Body parameter + +```json +{ + "conns_by_proto": { + "property1": 0, + "property2": 0 + }, + "num_comms": 0, + "rx_bytes": 0, + "rx_packets": 0, + "tx_bytes": 0, + "tx_packets": 0 +} +``` + +### Parameters + +| Name | In | Type | Required | Description | +| ------ | ---- | ---------------------------------------------------- | -------- | ------------- | +| `body` | body | [codersdk.AgentStats](schemas.md#codersdkagentstats) | true | Stats request | + +### Example responses + +> 200 Response + +```json +{ + "report_interval": 0 +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | -------------------------------------------------------------------- | +| 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 by means of one of the following methods: **CoderSessionToken**. + +## Submit workspace agent version + +### Code samples + +```shell +# Example request using curl +curl -X POST http://coder-server:8080/api/v2/workspaceagents/me/version \ + -H 'Content-Type: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`POST /workspaceagents/me/version` + +> Body parameter + +```json +{ + "version": "string" +} +``` + +### Parameters + +| Name | In | Type | Required | Description | +| ------ | ---- | ------------------------------------------------------------------------------------------------ | -------- | --------------- | +| `body` | body | [codersdk.PostWorkspaceAgentVersionRequest](schemas.md#codersdkpostworkspaceagentversionrequest) | true | Version request | + +### 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 by means of one of the following methods: **CoderSessionToken**. diff --git a/docs/api/schemas.md b/docs/api/schemas.md index d01652d468e97..be3449adadf1a 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -32,6 +32,48 @@ | `document` | string | true | | | | `signature` | string | true | | | +## codersdk.AgentStats + +```json +{ + "conns_by_proto": { + "property1": 0, + "property2": 0 + }, + "num_comms": 0, + "rx_bytes": 0, + "rx_packets": 0, + "tx_bytes": 0, + "tx_packets": 0 +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ------------------ | ------- | -------- | ------------ | ------------------------------------------------------------ | +| `conns_by_proto` | object | false | | Conns by proto is a count of connections by protocol. | +| » `[any property]` | integer | false | | | +| `num_comms` | integer | false | | Num comms is the number of connections received by an agent. | +| `rx_bytes` | integer | false | | Rx bytes is the number of received bytes. | +| `rx_packets` | integer | false | | Rx packets is the number of received packets. | +| `tx_bytes` | integer | false | | Tx bytes is the number of transmitted bytes. | +| `tx_packets` | integer | false | | Tx packets is the number of transmitted bytes. | + +## codersdk.AgentStatsResponse + +```json +{ + "report_interval": 0 +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ----------------- | ------- | -------- | ------------ | ------------------------------------------------------------------------------ | +| `report_interval` | integer | false | | Report interval is the duration after which the agent should send stats again. | + ## codersdk.AuditDiff ```json @@ -2177,6 +2219,38 @@ Parameter represents a set value for the scope. | `source_scheme` | `none` | | `source_scheme` | `data` | +## codersdk.PostWorkspaceAgentVersionRequest + +```json +{ + "version": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| --------- | ------ | -------- | ------------ | ----------- | +| `version` | string | false | | | + +## codersdk.PostWorkspaceAppHealthsRequest + +```json +{ + "healths": { + "property1": "string", + "property2": "string" + } +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ------------------ | ------ | -------- | ------------ | --------------------------------------------------------------------- | +| `healths` | object | false | | Healths is a map of the workspace app name and the health of the app. | +| » `[any property]` | string | false | | | + ## codersdk.PprofConfig ```json @@ -3170,6 +3244,24 @@ Parameter represents a set value for the scope. | --------------- | ------ | -------- | ------------ | ----------- | | `session_token` | string | false | | | +## codersdk.WorkspaceAgentGitAuthResponse + +```json +{ + "password": "string", + "url": "string", + "username": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ---------- | ------ | -------- | ------------ | ----------- | +| `password` | string | false | | | +| `url` | string | false | | | +| `username` | string | false | | | + ## codersdk.WorkspaceAgentMetadata ```json From ce8c7eacbbc72c97b8e7db96cd4092495c30b08f Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Mon, 2 Jan 2023 16:38:18 +0100 Subject: [PATCH 07/36] Agents --- coderd/apidoc/docs.go | 62 ++++++++++++++++++++++++++++++++++++++ coderd/apidoc/swagger.json | 52 ++++++++++++++++++++++++++++++++ coderd/gitsshkey.go | 8 +++++ coderd/workspaceagents.go | 9 ++++++ docs/api/agents.md | 55 +++++++++++++++++++++++++++++++++ docs/api/schemas.md | 16 ++++++++++ 6 files changed, 202 insertions(+) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 939d03ef63286..15111a5a9aaba 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -1016,6 +1016,29 @@ const docTemplate = `{ } } }, + "/workspaceagents/me/coordinate": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "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", + "responses": { + "101": { + "description": "Switching Protocols" + } + } + } + }, "/workspaceagents/me/gitauth": { "get": { "security": [ @@ -1060,6 +1083,34 @@ const docTemplate = `{ } } }, + "/workspaceagents/me/gitsshkey": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Agents" + ], + "summary": "Get workspace agent Git SSH key", + "operationId": "get-workspace-agent-git-ssh-key", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.AgentGitSSHKey" + } + } + } + } + }, "/workspaceagents/me/metadata": { "get": { "security": [ @@ -1706,6 +1757,17 @@ const docTemplate = `{ } } }, + "codersdk.AgentGitSSHKey": { + "type": "object", + "properties": { + "private_key": { + "type": "string" + }, + "public_key": { + "type": "string" + } + } + }, "codersdk.AgentStats": { "type": "object", "properties": { diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index dd59178737b2f..e6307dd643d5c 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -882,6 +882,25 @@ } } }, + "/workspaceagents/me/coordinate": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "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", + "responses": { + "101": { + "description": "Switching Protocols" + } + } + } + }, "/workspaceagents/me/gitauth": { "get": { "security": [ @@ -920,6 +939,28 @@ } } }, + "/workspaceagents/me/gitsshkey": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Agents"], + "summary": "Get workspace agent Git SSH key", + "operationId": "get-workspace-agent-git-ssh-key", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.AgentGitSSHKey" + } + } + } + } + }, "/workspaceagents/me/metadata": { "get": { "security": [ @@ -1488,6 +1529,17 @@ } } }, + "codersdk.AgentGitSSHKey": { + "type": "object", + "properties": { + "private_key": { + "type": "string" + }, + "public_key": { + "type": "string" + } + } + }, "codersdk.AgentStats": { "type": "object", "properties": { diff --git a/coderd/gitsshkey.go b/coderd/gitsshkey.go index 357f5b2e44dab..a0f15da2e9e0c 100644 --- a/coderd/gitsshkey.go +++ b/coderd/gitsshkey.go @@ -100,6 +100,14 @@ 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 +// @Router /workspaceagents/me/gitsshkey [get] func (api *API) agentGitSSHKey(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() agent := httpmw.WorkspaceAgent(r) diff --git a/coderd/workspaceagents.go b/coderd/workspaceagents.go index c6cd768f40f3a..ff8a23354e901 100644 --- a/coderd/workspaceagents.go +++ b/coderd/workspaceagents.go @@ -456,6 +456,15 @@ 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 +// @Security CoderSessionToken +// @Produce json +// @Tags Agents +// @Success 101 +// @Router /workspaceagents/me/coordinate [get] func (api *API) workspaceAgentCoordinate(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() diff --git a/docs/api/agents.md b/docs/api/agents.md index 2f287e1903daf..d001d5309d67c 100644 --- a/docs/api/agents.md +++ b/docs/api/agents.md @@ -180,6 +180,29 @@ curl -X POST http://coder-server:8080/api/v2/workspaceagents/me/app-health \ To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. +## Coordinate workspace agent via Tailnet + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/workspaceagents/me/coordinate \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /workspaceagents/me/coordinate` + +It accepts a WebSocket connection to an agent that listens to +incoming connections and publishes node updates. + +### 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 by means of one of the following methods: **CoderSessionToken**. + ## Get workspace agent Git auth ### Code samples @@ -220,6 +243,38 @@ curl -X GET http://coder-server:8080/api/v2/workspaceagents/me/gitauth?url=http% To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. +## Get workspace agent Git SSH key + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/workspaceagents/me/gitsshkey \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /workspaceagents/me/gitsshkey` + +### Example responses + +> 200 Response + +```json +{ + "private_key": "string", + "public_key": "string" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ------------------------------------------------------------ | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.AgentGitSSHKey](schemas.md#codersdkagentgitsshkey) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + ## Get authorized workspace agent metadata ### Code samples diff --git a/docs/api/schemas.md b/docs/api/schemas.md index be3449adadf1a..843ed32642484 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -32,6 +32,22 @@ | `document` | string | true | | | | `signature` | string | true | | | +## codersdk.AgentGitSSHKey + +```json +{ + "private_key": "string", + "public_key": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ------------- | ------ | -------- | ------------ | ----------- | +| `private_key` | string | false | | | +| `public_key` | string | false | | | + ## codersdk.AgentStats ```json From d2a9af51afb44e592e9c92008fc335ce0663d7af Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Mon, 2 Jan 2023 17:17:14 +0100 Subject: [PATCH 08/36] workspacebuilds.go --- coderd/apidoc/docs.go | 10 +- coderd/apidoc/swagger.json | 10 +- coderd/workspacebuilds.go | 10 +- docs/api/builds.md | 585 +++++++++++++++++++++++++++++++++++++ docs/api/workspaces.md | 582 ------------------------------------ docs/manifest.json | 4 + 6 files changed, 604 insertions(+), 597 deletions(-) create mode 100644 docs/api/builds.md diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 15111a5a9aaba..09b3ccfbfc8fb 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -1219,7 +1219,7 @@ const docTemplate = `{ "application/json" ], "tags": [ - "Workspaces" + "Builds" ], "summary": "Get workspace build", "operationId": "get-workspace-build", @@ -1253,7 +1253,7 @@ const docTemplate = `{ "application/json" ], "tags": [ - "Workspaces" + "Builds" ], "summary": "Cancel workspace build", "operationId": "cancel-workspace-build", @@ -1287,7 +1287,7 @@ const docTemplate = `{ "application/json" ], "tags": [ - "Workspaces" + "Builds" ], "summary": "Get workspace build logs", "operationId": "get-workspace-build-logs", @@ -1342,7 +1342,7 @@ const docTemplate = `{ "application/json" ], "tags": [ - "Workspaces" + "Builds" ], "summary": "Get workspace resources for workspace build", "operationId": "get-workspace-resources-for-workspace-build", @@ -1379,7 +1379,7 @@ const docTemplate = `{ "application/json" ], "tags": [ - "Workspaces" + "Builds" ], "summary": "Get provisioner state for workspace build", "operationId": "get-provisioner-state-for-workspace-build", diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index e6307dd643d5c..e93f620f9260c 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -1052,7 +1052,7 @@ } ], "produces": ["application/json"], - "tags": ["Workspaces"], + "tags": ["Builds"], "summary": "Get workspace build", "operationId": "get-workspace-build", "parameters": [ @@ -1082,7 +1082,7 @@ } ], "produces": ["application/json"], - "tags": ["Workspaces"], + "tags": ["Builds"], "summary": "Cancel workspace build", "operationId": "cancel-workspace-build", "parameters": [ @@ -1112,7 +1112,7 @@ } ], "produces": ["application/json"], - "tags": ["Workspaces"], + "tags": ["Builds"], "summary": "Get workspace build logs", "operationId": "get-workspace-build-logs", "parameters": [ @@ -1163,7 +1163,7 @@ } ], "produces": ["application/json"], - "tags": ["Workspaces"], + "tags": ["Builds"], "summary": "Get workspace resources for workspace build", "operationId": "get-workspace-resources-for-workspace-build", "parameters": [ @@ -1196,7 +1196,7 @@ } ], "produces": ["application/json"], - "tags": ["Workspaces"], + "tags": ["Builds"], "summary": "Get provisioner state for workspace build", "operationId": "get-provisioner-state-for-workspace-build", "parameters": [ diff --git a/coderd/workspacebuilds.go b/coderd/workspacebuilds.go index eee08bad5ec0d..ef8f9b3503ba9 100644 --- a/coderd/workspacebuilds.go +++ b/coderd/workspacebuilds.go @@ -27,7 +27,7 @@ import ( // @ID get-workspace-build // @Security CoderSessionToken // @Produce json -// @Tags Workspaces +// @Tags Builds // @Param workspacebuild path string true "Workspace build ID" // @Success 200 {object} codersdk.WorkspaceBuild // @Router /workspacebuilds/{workspacebuild} [get] @@ -547,7 +547,7 @@ func (api *API) postWorkspaceBuilds(rw http.ResponseWriter, r *http.Request) { // @ID cancel-workspace-build // @Security CoderSessionToken // @Produce json -// @Tags Workspaces +// @Tags Builds // @Param workspacebuild path string true "Workspace build ID" // @Success 200 {object} codersdk.Response // @Router /workspacebuilds/{workspacebuild}/cancel [patch] @@ -650,7 +650,7 @@ func (api *API) verifyUserCanCancelWorkspaceBuilds(ctx context.Context, userID u // @ID get-workspace-resources-for-workspace-build // @Security CoderSessionToken // @Produce json -// @Tags Workspaces +// @Tags Builds // @Param workspacebuild path string true "Workspace build ID" // @Success 200 {array} codersdk.WorkspaceResource // @Router /workspacebuilds/{workspacebuild}/resources [get] @@ -685,7 +685,7 @@ func (api *API) workspaceBuildResources(rw http.ResponseWriter, r *http.Request) // @ID get-workspace-build-logs // @Security CoderSessionToken // @Produce json -// @Tags Workspaces +// @Tags Builds // @Param workspacebuild path string true "Workspace build ID" // @Param before query int false "Before Unix timestamp" // @Param after query int false "After Unix timestamp" @@ -723,7 +723,7 @@ func (api *API) workspaceBuildLogs(rw http.ResponseWriter, r *http.Request) { // @ID get-provisioner-state-for-workspace-build // @Security CoderSessionToken // @Produce json -// @Tags Workspaces +// @Tags Builds // @Param workspacebuild path string true "Workspace build ID" // @Success 200 {object} codersdk.WorkspaceBuild // @Router /workspacebuilds/{workspacebuild}/state [get] diff --git a/docs/api/builds.md b/docs/api/builds.md new file mode 100644 index 0000000000000..a2af49243e338 --- /dev/null +++ b/docs/api/builds.md @@ -0,0 +1,585 @@ +# Builds + +> This page is incomplete, stay tuned. + +## Get workspace build + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild} \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /workspacebuilds/{workspacebuild}` + +### Parameters + +| Name | In | Type | Required | Description | +| ---------------- | ---- | ------ | -------- | ------------------ | +| `workspacebuild` | path | string | true | Workspace build ID | + +### Example responses + +> 200 Response + +```json +{ + "build_number": 0, + "created_at": "2019-08-24T14:15:22Z", + "daily_cost": 0, + "deadline": "2019-08-24T14:15:22Z", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3", + "initiator_name": "string", + "job": { + "canceled_at": "2019-08-24T14:15:22Z", + "completed_at": "2019-08-24T14:15:22Z", + "created_at": "2019-08-24T14:15:22Z", + "error": "string", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" + }, + "reason": "initiator", + "resources": [ + { + "agents": [ + { + "apps": [ + { + "command": "string", + "display_name": "string", + "external": true, + "health": "string", + "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" + } + ], + "created_at": "2019-08-24T14:15:22Z", + "daily_cost": 0, + "hide": true, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f", + "metadata": [ + { + "key": "string", + "sensitive": true, + "value": "string" + } + ], + "name": "string", + "type": "string", + "workspace_transition": "start" + } + ], + "status": "pending", + "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1", + "template_version_name": "string", + "transition": "start", + "updated_at": "2019-08-24T14:15:22Z", + "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9", + "workspace_name": "string", + "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7", + "workspace_owner_name": "string" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ------------------------------------------------------------ | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.WorkspaceBuild](schemas.md#codersdkworkspacebuild) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Cancel workspace build + +### Code samples + +```shell +# Example request using curl +curl -X PATCH http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/cancel \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`PATCH /workspacebuilds/{workspacebuild}/cancel` + +### Parameters + +| Name | In | Type | Required | Description | +| ---------------- | ---- | ------ | -------- | ------------------ | +| `workspacebuild` | path | string | true | Workspace build ID | + +### Example responses + +> 200 Response + +```json +{ + "detail": "string", + "message": "string", + "validations": [ + { + "detail": "string", + "field": "string" + } + ] +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ------------------------------------------------ | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.Response](schemas.md#codersdkresponse) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Get workspace build logs + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/logs \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /workspacebuilds/{workspacebuild}/logs` + +### Parameters + +| Name | In | Type | Required | Description | +| ---------------- | ----- | ------- | -------- | --------------------- | +| `workspacebuild` | path | string | true | Workspace build ID | +| `before` | query | integer | false | Before Unix timestamp | +| `after` | query | integer | false | After Unix timestamp | +| `follow` | query | boolean | false | Follow log stream | + +### Example responses + +> 200 Response + +```json +[ + { + "created_at": "2019-08-24T14:15:22Z", + "id": 0, + "log_level": "trace", + "log_source": "string", + "output": "string", + "stage": "string" + } +] +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | --------------------------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | array of [codersdk.ProvisionerJobLog](schemas.md#codersdkprovisionerjoblog) | + +

Response Schema

+ +Status Code **200** + +| Name | Type | Required | Restrictions | Description | +| -------------- | ------- | -------- | ------------ | ----------- | +| `[array item]` | array | false | | | +| `» created_at` | string | false | | | +| `» id` | integer | false | | | +| `» log_level` | string | false | | | +| `» log_source` | string | false | | | +| `» output` | string | false | | | +| `» stage` | string | false | | | + +#### Enumerated Values + +| Property | Value | +| ----------- | ------- | +| `log_level` | `trace` | +| `log_level` | `debug` | +| `log_level` | `info` | +| `log_level` | `warn` | +| `log_level` | `error` | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Get workspace resources for workspace build + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/resources \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /workspacebuilds/{workspacebuild}/resources` + +### Parameters + +| Name | In | Type | Required | Description | +| ---------------- | ---- | ------ | -------- | ------------------ | +| `workspacebuild` | path | string | true | Workspace build ID | + +### Example responses + +> 200 Response + +```json +[ + { + "agents": [ + { + "apps": [ + { + "command": "string", + "display_name": "string", + "external": true, + "health": "string", + "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" + } + ], + "created_at": "2019-08-24T14:15:22Z", + "daily_cost": 0, + "hide": true, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f", + "metadata": [ + { + "key": "string", + "sensitive": true, + "value": "string" + } + ], + "name": "string", + "type": "string", + "workspace_transition": "start" + } +] +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | --------------------------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | array of [codersdk.WorkspaceResource](schemas.md#codersdkworkspaceresource) | + +

Response Schema

+ +Status Code **200** + +| Name | Type | Required | Restrictions | Description | +| ------------------------------- | ---------------------- | -------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `[array item]` | array | false | | | +| `» agents` | array | false | | | +| `»» apps` | array | false | | | +| `»»» command` | string | false | | | +| `»»» display_name` | string | false | | DisplayName is a friendly name for the app. | +| `»»» external` | boolean | false | | External specifies whether the URL should be opened externally on
the client or not. | +| `»»» health` | string | false | | | +| `»»» healthcheck` | `codersdk.Healthcheck` | false | | | +| `»»»» interval` | integer | false | | Interval specifies the seconds between each health check. | +| `»»»» threshold` | integer | false | | Threshold specifies the number of consecutive failed health checks before returning "unhealthy". | +| `»»»» url` | string | false | | URL specifies the endpoint to check for the app health. | +| `»»» icon` | string | false | | Icon is a relative path or external URL that specifies
an icon to be displayed in the dashboard. | +| `»»» id` | string | false | | | +| `»»» sharing_level` | string | false | | | +| `»»» slug` | string | false | | Slug is a unique identifier within the agent. | +| `»»» subdomain` | boolean | false | | Subdomain denotes whether the app should be accessed via a path on the
`coder server` or via a hostname-based dev URL. If this is set to true
and there is no app wildcard configured on the server, the app will not
be accessible in the UI. | +| `»»» url` | string | false | | URL is the address being proxied to inside the workspace.
If external is specified, this will be opened on the client. | +| `»» architecture` | string | false | | | +| `»» connection_timeout_seconds` | integer | false | | | +| `»» created_at` | string | false | | | +| `»» directory` | string | false | | | +| `»» disconnected_at` | string | false | | | +| `»» environment_variables` | object | false | | | +| `»»» [any property]` | string | false | | | +| `»» first_connected_at` | string | false | | | +| `»» id` | string | false | | | +| `»» instance_id` | string | false | | | +| `»» last_connected_at` | string | false | | | +| `»» latency` | object | false | | DERPLatency is mapped by region name (e.g. "New York City", "Seattle"). | +| `»»» [any property]` | `codersdk.DERPRegion` | false | | | +| `»»»» latency_ms` | number | false | | | +| `»»»» preferred` | boolean | false | | | +| `»» name` | string | false | | | +| `»» operating_system` | string | false | | | +| `»» resource_id` | string | false | | | +| `»» startup_script` | string | false | | | +| `»» status` | string | false | | | +| `»» troubleshooting_url` | string | false | | | +| `»» updated_at` | string | false | | | +| `»» version` | string | false | | | +| `» created_at` | string | false | | | +| `» daily_cost` | integer | false | | | +| `» hide` | boolean | false | | | +| `» icon` | string | false | | | +| `» id` | string | false | | | +| `» job_id` | string | false | | | +| `» metadata` | array | false | | | +| `»» key` | string | false | | | +| `»» sensitive` | boolean | false | | | +| `»» value` | string | false | | | +| `» name` | string | false | | | +| `» type` | string | false | | | +| `» workspace_transition` | string | false | | | + +#### Enumerated Values + +| Property | Value | +| ---------------------- | --------------- | +| `sharing_level` | `owner` | +| `sharing_level` | `authenticated` | +| `sharing_level` | `public` | +| `status` | `connecting` | +| `status` | `connected` | +| `status` | `disconnected` | +| `status` | `timeout` | +| `workspace_transition` | `start` | +| `workspace_transition` | `stop` | +| `workspace_transition` | `delete` | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Get provisioner state for workspace build + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/state \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /workspacebuilds/{workspacebuild}/state` + +### Parameters + +| Name | In | Type | Required | Description | +| ---------------- | ---- | ------ | -------- | ------------------ | +| `workspacebuild` | path | string | true | Workspace build ID | + +### Example responses + +> 200 Response + +```json +{ + "build_number": 0, + "created_at": "2019-08-24T14:15:22Z", + "daily_cost": 0, + "deadline": "2019-08-24T14:15:22Z", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3", + "initiator_name": "string", + "job": { + "canceled_at": "2019-08-24T14:15:22Z", + "completed_at": "2019-08-24T14:15:22Z", + "created_at": "2019-08-24T14:15:22Z", + "error": "string", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" + }, + "reason": "initiator", + "resources": [ + { + "agents": [ + { + "apps": [ + { + "command": "string", + "display_name": "string", + "external": true, + "health": "string", + "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" + } + ], + "created_at": "2019-08-24T14:15:22Z", + "daily_cost": 0, + "hide": true, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f", + "metadata": [ + { + "key": "string", + "sensitive": true, + "value": "string" + } + ], + "name": "string", + "type": "string", + "workspace_transition": "start" + } + ], + "status": "pending", + "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1", + "template_version_name": "string", + "transition": "start", + "updated_at": "2019-08-24T14:15:22Z", + "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9", + "workspace_name": "string", + "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7", + "workspace_owner_name": "string" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ------------------------------------------------------------ | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.WorkspaceBuild](schemas.md#codersdkworkspacebuild) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. diff --git a/docs/api/workspaces.md b/docs/api/workspaces.md index 288465fcab3e5..9254214759b09 100644 --- a/docs/api/workspaces.md +++ b/docs/api/workspaces.md @@ -323,588 +323,6 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/workspace/{workspacenam To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. -## Get workspace build - -### Code samples - -```shell -# Example request using curl -curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild} \ - -H 'Accept: application/json' \ - -H 'Coder-Session-Token: API_KEY' -``` - -`GET /workspacebuilds/{workspacebuild}` - -### Parameters - -| Name | In | Type | Required | Description | -| ---------------- | ---- | ------ | -------- | ------------------ | -| `workspacebuild` | path | string | true | Workspace build ID | - -### Example responses - -> 200 Response - -```json -{ - "build_number": 0, - "created_at": "2019-08-24T14:15:22Z", - "daily_cost": 0, - "deadline": "2019-08-24T14:15:22Z", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3", - "initiator_name": "string", - "job": { - "canceled_at": "2019-08-24T14:15:22Z", - "completed_at": "2019-08-24T14:15:22Z", - "created_at": "2019-08-24T14:15:22Z", - "error": "string", - "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "started_at": "2019-08-24T14:15:22Z", - "status": "pending", - "tags": { - "property1": "string", - "property2": "string" - }, - "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" - }, - "reason": "initiator", - "resources": [ - { - "agents": [ - { - "apps": [ - { - "command": "string", - "display_name": "string", - "external": true, - "health": "string", - "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" - } - ], - "created_at": "2019-08-24T14:15:22Z", - "daily_cost": 0, - "hide": true, - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f", - "metadata": [ - { - "key": "string", - "sensitive": true, - "value": "string" - } - ], - "name": "string", - "type": "string", - "workspace_transition": "start" - } - ], - "status": "pending", - "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1", - "template_version_name": "string", - "transition": "start", - "updated_at": "2019-08-24T14:15:22Z", - "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9", - "workspace_name": "string", - "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7", - "workspace_owner_name": "string" -} -``` - -### Responses - -| Status | Meaning | Description | Schema | -| ------ | ------------------------------------------------------- | ----------- | ------------------------------------------------------------ | -| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.WorkspaceBuild](schemas.md#codersdkworkspacebuild) | - -To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. - -## Cancel workspace build - -### Code samples - -```shell -# Example request using curl -curl -X PATCH http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/cancel \ - -H 'Accept: application/json' \ - -H 'Coder-Session-Token: API_KEY' -``` - -`PATCH /workspacebuilds/{workspacebuild}/cancel` - -### Parameters - -| Name | In | Type | Required | Description | -| ---------------- | ---- | ------ | -------- | ------------------ | -| `workspacebuild` | path | string | true | Workspace build ID | - -### Example responses - -> 200 Response - -```json -{ - "detail": "string", - "message": "string", - "validations": [ - { - "detail": "string", - "field": "string" - } - ] -} -``` - -### Responses - -| Status | Meaning | Description | Schema | -| ------ | ------------------------------------------------------- | ----------- | ------------------------------------------------ | -| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.Response](schemas.md#codersdkresponse) | - -To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. - -## Get workspace build logs - -### Code samples - -```shell -# Example request using curl -curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/logs \ - -H 'Accept: application/json' \ - -H 'Coder-Session-Token: API_KEY' -``` - -`GET /workspacebuilds/{workspacebuild}/logs` - -### Parameters - -| Name | In | Type | Required | Description | -| ---------------- | ----- | ------- | -------- | --------------------- | -| `workspacebuild` | path | string | true | Workspace build ID | -| `before` | query | integer | false | Before Unix timestamp | -| `after` | query | integer | false | After Unix timestamp | -| `follow` | query | boolean | false | Follow log stream | - -### Example responses - -> 200 Response - -```json -[ - { - "created_at": "2019-08-24T14:15:22Z", - "id": 0, - "log_level": "trace", - "log_source": "string", - "output": "string", - "stage": "string" - } -] -``` - -### Responses - -| Status | Meaning | Description | Schema | -| ------ | ------------------------------------------------------- | ----------- | --------------------------------------------------------------------------- | -| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | array of [codersdk.ProvisionerJobLog](schemas.md#codersdkprovisionerjoblog) | - -

Response Schema

- -Status Code **200** - -| Name | Type | Required | Restrictions | Description | -| -------------- | ------- | -------- | ------------ | ----------- | -| `[array item]` | array | false | | | -| `» created_at` | string | false | | | -| `» id` | integer | false | | | -| `» log_level` | string | false | | | -| `» log_source` | string | false | | | -| `» output` | string | false | | | -| `» stage` | string | false | | | - -#### Enumerated Values - -| Property | Value | -| ----------- | ------- | -| `log_level` | `trace` | -| `log_level` | `debug` | -| `log_level` | `info` | -| `log_level` | `warn` | -| `log_level` | `error` | - -To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. - -## Get workspace resources for workspace build - -### Code samples - -```shell -# Example request using curl -curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/resources \ - -H 'Accept: application/json' \ - -H 'Coder-Session-Token: API_KEY' -``` - -`GET /workspacebuilds/{workspacebuild}/resources` - -### Parameters - -| Name | In | Type | Required | Description | -| ---------------- | ---- | ------ | -------- | ------------------ | -| `workspacebuild` | path | string | true | Workspace build ID | - -### Example responses - -> 200 Response - -```json -[ - { - "agents": [ - { - "apps": [ - { - "command": "string", - "display_name": "string", - "external": true, - "health": "string", - "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" - } - ], - "created_at": "2019-08-24T14:15:22Z", - "daily_cost": 0, - "hide": true, - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f", - "metadata": [ - { - "key": "string", - "sensitive": true, - "value": "string" - } - ], - "name": "string", - "type": "string", - "workspace_transition": "start" - } -] -``` - -### Responses - -| Status | Meaning | Description | Schema | -| ------ | ------------------------------------------------------- | ----------- | --------------------------------------------------------------------------- | -| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | array of [codersdk.WorkspaceResource](schemas.md#codersdkworkspaceresource) | - -

Response Schema

- -Status Code **200** - -| Name | Type | Required | Restrictions | Description | -| ------------------------------- | ---------------------- | -------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `[array item]` | array | false | | | -| `» agents` | array | false | | | -| `»» apps` | array | false | | | -| `»»» command` | string | false | | | -| `»»» display_name` | string | false | | DisplayName is a friendly name for the app. | -| `»»» external` | boolean | false | | External specifies whether the URL should be opened externally on
the client or not. | -| `»»» health` | string | false | | | -| `»»» healthcheck` | `codersdk.Healthcheck` | false | | | -| `»»»» interval` | integer | false | | Interval specifies the seconds between each health check. | -| `»»»» threshold` | integer | false | | Threshold specifies the number of consecutive failed health checks before returning "unhealthy". | -| `»»»» url` | string | false | | URL specifies the endpoint to check for the app health. | -| `»»» icon` | string | false | | Icon is a relative path or external URL that specifies
an icon to be displayed in the dashboard. | -| `»»» id` | string | false | | | -| `»»» sharing_level` | string | false | | | -| `»»» slug` | string | false | | Slug is a unique identifier within the agent. | -| `»»» subdomain` | boolean | false | | Subdomain denotes whether the app should be accessed via a path on the
`coder server` or via a hostname-based dev URL. If this is set to true
and there is no app wildcard configured on the server, the app will not
be accessible in the UI. | -| `»»» url` | string | false | | URL is the address being proxied to inside the workspace.
If external is specified, this will be opened on the client. | -| `»» architecture` | string | false | | | -| `»» connection_timeout_seconds` | integer | false | | | -| `»» created_at` | string | false | | | -| `»» directory` | string | false | | | -| `»» disconnected_at` | string | false | | | -| `»» environment_variables` | object | false | | | -| `»»» [any property]` | string | false | | | -| `»» first_connected_at` | string | false | | | -| `»» id` | string | false | | | -| `»» instance_id` | string | false | | | -| `»» last_connected_at` | string | false | | | -| `»» latency` | object | false | | DERPLatency is mapped by region name (e.g. "New York City", "Seattle"). | -| `»»» [any property]` | `codersdk.DERPRegion` | false | | | -| `»»»» latency_ms` | number | false | | | -| `»»»» preferred` | boolean | false | | | -| `»» name` | string | false | | | -| `»» operating_system` | string | false | | | -| `»» resource_id` | string | false | | | -| `»» startup_script` | string | false | | | -| `»» status` | string | false | | | -| `»» troubleshooting_url` | string | false | | | -| `»» updated_at` | string | false | | | -| `»» version` | string | false | | | -| `» created_at` | string | false | | | -| `» daily_cost` | integer | false | | | -| `» hide` | boolean | false | | | -| `» icon` | string | false | | | -| `» id` | string | false | | | -| `» job_id` | string | false | | | -| `» metadata` | array | false | | | -| `»» key` | string | false | | | -| `»» sensitive` | boolean | false | | | -| `»» value` | string | false | | | -| `» name` | string | false | | | -| `» type` | string | false | | | -| `» workspace_transition` | string | false | | | - -#### Enumerated Values - -| Property | Value | -| ---------------------- | --------------- | -| `sharing_level` | `owner` | -| `sharing_level` | `authenticated` | -| `sharing_level` | `public` | -| `status` | `connecting` | -| `status` | `connected` | -| `status` | `disconnected` | -| `status` | `timeout` | -| `workspace_transition` | `start` | -| `workspace_transition` | `stop` | -| `workspace_transition` | `delete` | - -To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. - -## Get provisioner state for workspace build - -### Code samples - -```shell -# Example request using curl -curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/state \ - -H 'Accept: application/json' \ - -H 'Coder-Session-Token: API_KEY' -``` - -`GET /workspacebuilds/{workspacebuild}/state` - -### Parameters - -| Name | In | Type | Required | Description | -| ---------------- | ---- | ------ | -------- | ------------------ | -| `workspacebuild` | path | string | true | Workspace build ID | - -### Example responses - -> 200 Response - -```json -{ - "build_number": 0, - "created_at": "2019-08-24T14:15:22Z", - "daily_cost": 0, - "deadline": "2019-08-24T14:15:22Z", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3", - "initiator_name": "string", - "job": { - "canceled_at": "2019-08-24T14:15:22Z", - "completed_at": "2019-08-24T14:15:22Z", - "created_at": "2019-08-24T14:15:22Z", - "error": "string", - "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "started_at": "2019-08-24T14:15:22Z", - "status": "pending", - "tags": { - "property1": "string", - "property2": "string" - }, - "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" - }, - "reason": "initiator", - "resources": [ - { - "agents": [ - { - "apps": [ - { - "command": "string", - "display_name": "string", - "external": true, - "health": "string", - "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" - } - ], - "created_at": "2019-08-24T14:15:22Z", - "daily_cost": 0, - "hide": true, - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f", - "metadata": [ - { - "key": "string", - "sensitive": true, - "value": "string" - } - ], - "name": "string", - "type": "string", - "workspace_transition": "start" - } - ], - "status": "pending", - "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1", - "template_version_name": "string", - "transition": "start", - "updated_at": "2019-08-24T14:15:22Z", - "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9", - "workspace_name": "string", - "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7", - "workspace_owner_name": "string" -} -``` - -### Responses - -| Status | Meaning | Description | Schema | -| ------ | ------------------------------------------------------- | ----------- | ------------------------------------------------------------ | -| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.WorkspaceBuild](schemas.md#codersdkworkspacebuild) | - -To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. - ## List workspaces ### Code samples diff --git a/docs/manifest.json b/docs/manifest.json index ee27d96a9c510..079735f2800bb 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -365,6 +365,10 @@ "title": "Agents", "path": "./api/agents.md" }, + { + "title": "Builds", + "path": "./api/builds.md" + }, { "title": "Schemas", "path": "./api/schemas.md" From f37c6b3ce2d77b66334e3f5c37960d56d62fcec4 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Tue, 3 Jan 2023 10:26:23 +0100 Subject: [PATCH 09/36] /workspaces --- coderd/apidoc/docs.go | 146 +++++++++++ coderd/apidoc/swagger.json | 131 ++++++++++ coderd/workspacebuilds.go | 25 ++ coderd/workspaceresourceauth.go | 16 +- docs/api/builds.md | 440 ++++++++++++++++++++++++++++++++ docs/api/schemas.md | 41 +++ 6 files changed, 791 insertions(+), 8 deletions(-) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 09b3ccfbfc8fb..0984d5eb2ccef 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -1517,6 +1517,112 @@ const docTemplate = `{ } } }, + "/workspaces/{id}/builds": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Builds" + ], + "summary": "Get workspace builds by workspace ID", + "operationId": "get-workspace-builds-by-workspace-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "After ID", + "name": "after_id", + "in": "query" + }, + { + "type": "integer", + "description": "Page limit", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "description": "Page offset", + "name": "offset", + "in": "query" + }, + { + "type": "string", + "format": "date-time", + "description": "Since timestamp", + "name": "since", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceBuild" + } + } + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Builds" + ], + "summary": "Create workspace build", + "operationId": "create-workspace-build", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Create workspace build request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateWorkspaceBuildRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceBuild" + } + } + } + } + }, "/workspaces/{workspace}": { "patch": { "security": [ @@ -2104,6 +2210,46 @@ const docTemplate = `{ } } }, + "codersdk.CreateWorkspaceBuildRequest": { + "type": "object", + "required": [ + "transition" + ], + "properties": { + "dry_run": { + "type": "boolean" + }, + "orphan": { + "description": "Orphan may be set for the Destroy transition.", + "type": "boolean" + }, + "parameter_values": { + "description": "ParameterValues are optional. It will write params to the 'workspace' scope.\nThis will overwrite any existing parameters with the same name.\nThis will not delete old params not included in this list.", + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.CreateParameterRequest" + } + }, + "state": { + "type": "array", + "items": { + "type": "integer" + } + }, + "template_version_id": { + "type": "string" + }, + "transition": { + "type": "string", + "enum": [ + "create", + "start", + "stop", + "delete" + ] + } + } + }, "codersdk.DERP": { "type": "object", "properties": { diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index e93f620f9260c..0dc03ac3ddd8f 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -1320,6 +1320,104 @@ } } }, + "/workspaces/{id}/builds": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Builds"], + "summary": "Get workspace builds by workspace ID", + "operationId": "get-workspace-builds-by-workspace-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "After ID", + "name": "after_id", + "in": "query" + }, + { + "type": "integer", + "description": "Page limit", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "description": "Page offset", + "name": "offset", + "in": "query" + }, + { + "type": "string", + "format": "date-time", + "description": "Since timestamp", + "name": "since", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceBuild" + } + } + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Builds"], + "summary": "Create workspace build", + "operationId": "create-workspace-build", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Create workspace build request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateWorkspaceBuildRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceBuild" + } + } + } + } + }, "/workspaces/{workspace}": { "patch": { "security": [ @@ -1852,6 +1950,39 @@ } } }, + "codersdk.CreateWorkspaceBuildRequest": { + "type": "object", + "required": ["transition"], + "properties": { + "dry_run": { + "type": "boolean" + }, + "orphan": { + "description": "Orphan may be set for the Destroy transition.", + "type": "boolean" + }, + "parameter_values": { + "description": "ParameterValues are optional. It will write params to the 'workspace' scope.\nThis will overwrite any existing parameters with the same name.\nThis will not delete old params not included in this list.", + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.CreateParameterRequest" + } + }, + "state": { + "type": "array", + "items": { + "type": "integer" + } + }, + "template_version_id": { + "type": "string" + }, + "transition": { + "type": "string", + "enum": ["create", "start", "stop", "delete"] + } + } + }, "codersdk.DERP": { "type": "object", "properties": { diff --git a/coderd/workspacebuilds.go b/coderd/workspacebuilds.go index ef8f9b3503ba9..19ea83a06376c 100644 --- a/coderd/workspacebuilds.go +++ b/coderd/workspacebuilds.go @@ -72,6 +72,18 @@ func (api *API) workspaceBuild(rw http.ResponseWriter, r *http.Request) { httpapi.Write(ctx, rw, http.StatusOK, apiBuild) } +// @Summary Get workspace builds by workspace ID +// @ID get-workspace-builds-by-workspace-id +// @Security CoderSessionToken +// @Produce json +// @Tags Builds +// @Param id 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] func (api *API) workspaceBuilds(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() workspace := httpmw.WorkspaceParam(r) @@ -262,6 +274,19 @@ func (api *API) workspaceBuildByBuildNumber(rw http.ResponseWriter, r *http.Requ httpapi.Write(ctx, rw, http.StatusOK, apiBuild) } +// @Summary Create workspace build +// @ID create-workspace-build +// @Security CoderSessionToken +// @Accepts json +// @Produce json +// @Tags Builds +// @Param id 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] +// +// Azure supports instance identity verification: +// https://docs.microsoft.com/en-us/azure/virtual-machines/windows/instance-metadata-service?tabs=linux#tabgroup_14 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 ea72b794ada37..8da31d1cdd96a 100644 --- a/coderd/workspaceresourceauth.go +++ b/coderd/workspaceresourceauth.go @@ -45,10 +45,6 @@ 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 @@ -57,6 +53,10 @@ func (api *API) postWorkspaceAuthAzureInstanceIdentity(rw http.ResponseWriter, r // @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,10 +74,6 @@ 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 @@ -86,6 +82,10 @@ func (api *API) postWorkspaceAuthAWSInstanceIdentity(rw http.ResponseWriter, r * // @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/docs/api/builds.md b/docs/api/builds.md index a2af49243e338..2eea39745c4ea 100644 --- a/docs/api/builds.md +++ b/docs/api/builds.md @@ -583,3 +583,443 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/sta | 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.WorkspaceBuild](schemas.md#codersdkworkspacebuild) | To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Get workspace builds by workspace ID + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/workspaces/{id}/builds \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /workspaces/{id}/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 | + +### Example responses + +> 200 Response + +```json +[ + { + "build_number": 0, + "created_at": "2019-08-24T14:15:22Z", + "daily_cost": 0, + "deadline": "2019-08-24T14:15:22Z", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3", + "initiator_name": "string", + "job": { + "canceled_at": "2019-08-24T14:15:22Z", + "completed_at": "2019-08-24T14:15:22Z", + "created_at": "2019-08-24T14:15:22Z", + "error": "string", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" + }, + "reason": "initiator", + "resources": [ + { + "agents": [ + { + "apps": [ + { + "command": "string", + "display_name": "string", + "external": true, + "health": "string", + "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" + } + ], + "created_at": "2019-08-24T14:15:22Z", + "daily_cost": 0, + "hide": true, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f", + "metadata": [ + { + "key": "string", + "sensitive": true, + "value": "string" + } + ], + "name": "string", + "type": "string", + "workspace_transition": "start" + } + ], + "status": "pending", + "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1", + "template_version_name": "string", + "transition": "start", + "updated_at": "2019-08-24T14:15:22Z", + "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9", + "workspace_name": "string", + "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7", + "workspace_owner_name": "string" + } +] +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | --------------------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | array of [codersdk.WorkspaceBuild](schemas.md#codersdkworkspacebuild) | + +

Response Schema

+ +Status Code **200** + +| Name | Type | Required | Restrictions | Description | +| -------------------------------- | ------------------------- | -------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `[array item]` | array | false | | | +| `» build_number` | integer | false | | | +| `» created_at` | string | false | | | +| `» daily_cost` | integer | false | | | +| `» deadline` | string | false | | | +| `» id` | string | false | | | +| `» initiator_id` | string | false | | | +| `» initiator_name` | string | false | | | +| `» job` | `codersdk.ProvisionerJob` | false | | | +| `»» canceled_at` | string | false | | | +| `»» completed_at` | string | false | | | +| `»» created_at` | string | false | | | +| `»» error` | string | false | | | +| `»» file_id` | string | false | | | +| `»» id` | string | false | | | +| `»» started_at` | string | false | | | +| `»» status` | string | false | | | +| `»» tags` | object | false | | | +| `»»» [any property]` | string | false | | | +| `»» worker_id` | string | false | | | +| `» reason` | string | false | | | +| `» resources` | array | false | | | +| `»» agents` | array | false | | | +| `»»» apps` | array | false | | | +| `»»»» command` | string | false | | | +| `»»»» display_name` | string | false | | DisplayName is a friendly name for the app. | +| `»»»» external` | boolean | false | | External specifies whether the URL should be opened externally on
the client or not. | +| `»»»» health` | string | false | | | +| `»»»» healthcheck` | `codersdk.Healthcheck` | false | | | +| `»»»»» interval` | integer | false | | Interval specifies the seconds between each health check. | +| `»»»»» threshold` | integer | false | | Threshold specifies the number of consecutive failed health checks before returning "unhealthy". | +| `»»»»» url` | string | false | | URL specifies the endpoint to check for the app health. | +| `»»»» icon` | string | false | | Icon is a relative path or external URL that specifies
an icon to be displayed in the dashboard. | +| `»»»» id` | string | false | | | +| `»»»» sharing_level` | string | false | | | +| `»»»» slug` | string | false | | Slug is a unique identifier within the agent. | +| `»»»» subdomain` | boolean | false | | Subdomain denotes whether the app should be accessed via a path on the
`coder server` or via a hostname-based dev URL. If this is set to true
and there is no app wildcard configured on the server, the app will not
be accessible in the UI. | +| `»»»» url` | string | false | | URL is the address being proxied to inside the workspace.
If external is specified, this will be opened on the client. | +| `»»» architecture` | string | false | | | +| `»»» connection_timeout_seconds` | integer | false | | | +| `»»» created_at` | string | false | | | +| `»»» directory` | string | false | | | +| `»»» disconnected_at` | string | false | | | +| `»»» environment_variables` | object | false | | | +| `»»»» [any property]` | string | false | | | +| `»»» first_connected_at` | string | false | | | +| `»»» id` | string | false | | | +| `»»» instance_id` | string | false | | | +| `»»» last_connected_at` | string | false | | | +| `»»» latency` | object | false | | DERPLatency is mapped by region name (e.g. "New York City", "Seattle"). | +| `»»»» [any property]` | `codersdk.DERPRegion` | false | | | +| `»»»»» latency_ms` | number | false | | | +| `»»»»» preferred` | boolean | false | | | +| `»»» name` | string | false | | | +| `»»» operating_system` | string | false | | | +| `»»» resource_id` | string | false | | | +| `»»» startup_script` | string | false | | | +| `»»» status` | string | false | | | +| `»»» troubleshooting_url` | string | false | | | +| `»»» updated_at` | string | false | | | +| `»»» version` | string | false | | | +| `»» created_at` | string | false | | | +| `»» daily_cost` | integer | false | | | +| `»» hide` | boolean | false | | | +| `»» icon` | string | false | | | +| `»» id` | string | false | | | +| `»» job_id` | string | false | | | +| `»» metadata` | array | false | | | +| `»»» key` | string | false | | | +| `»»» sensitive` | boolean | false | | | +| `»»» value` | string | false | | | +| `»» name` | string | false | | | +| `»» type` | string | false | | | +| `»» workspace_transition` | string | false | | | +| `» status` | string | false | | | +| `» template_version_id` | string | false | | | +| `» template_version_name` | string | false | | | +| `» transition` | string | false | | | +| `» updated_at` | string | false | | | +| `» workspace_id` | string | false | | | +| `» workspace_name` | string | false | | | +| `» workspace_owner_id` | string | false | | | +| `» workspace_owner_name` | string | false | | | + +#### Enumerated Values + +| Property | Value | +| ---------------------- | --------------- | +| `status` | `pending` | +| `status` | `running` | +| `status` | `succeeded` | +| `status` | `canceling` | +| `status` | `canceled` | +| `status` | `failed` | +| `reason` | `initiator` | +| `reason` | `autostart` | +| `reason` | `autostop` | +| `sharing_level` | `owner` | +| `sharing_level` | `authenticated` | +| `sharing_level` | `public` | +| `status` | `connecting` | +| `status` | `connected` | +| `status` | `disconnected` | +| `status` | `timeout` | +| `workspace_transition` | `start` | +| `workspace_transition` | `stop` | +| `workspace_transition` | `delete` | +| `status` | `pending` | +| `status` | `starting` | +| `status` | `running` | +| `status` | `stopping` | +| `status` | `stopped` | +| `status` | `failed` | +| `status` | `canceling` | +| `status` | `canceled` | +| `status` | `deleting` | +| `status` | `deleted` | +| `transition` | `start` | +| `transition` | `stop` | +| `transition` | `delete` | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Create workspace build + +### Code samples + +```shell +# Example request using curl +curl -X POST http://coder-server:8080/api/v2/workspaces/{id}/builds \ + -H 'Content-Type: application/json' \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`POST /workspaces/{id}/builds` + +> Body parameter + +```json +{ + "dry_run": true, + "orphan": true, + "parameter_values": [ + { + "copy_from_parameter": "string", + "destination_scheme": "none", + "name": "string", + "source_scheme": "none", + "source_value": "string" + } + ], + "state": [0], + "template_version_id": "string", + "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 | + +### Example responses + +> 200 Response + +```json +{ + "build_number": 0, + "created_at": "2019-08-24T14:15:22Z", + "daily_cost": 0, + "deadline": "2019-08-24T14:15:22Z", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3", + "initiator_name": "string", + "job": { + "canceled_at": "2019-08-24T14:15:22Z", + "completed_at": "2019-08-24T14:15:22Z", + "created_at": "2019-08-24T14:15:22Z", + "error": "string", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" + }, + "reason": "initiator", + "resources": [ + { + "agents": [ + { + "apps": [ + { + "command": "string", + "display_name": "string", + "external": true, + "health": "string", + "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" + } + ], + "created_at": "2019-08-24T14:15:22Z", + "daily_cost": 0, + "hide": true, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f", + "metadata": [ + { + "key": "string", + "sensitive": true, + "value": "string" + } + ], + "name": "string", + "type": "string", + "workspace_transition": "start" + } + ], + "status": "pending", + "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1", + "template_version_name": "string", + "transition": "start", + "updated_at": "2019-08-24T14:15:22Z", + "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9", + "workspace_name": "string", + "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7", + "workspace_owner_name": "string" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ------------------------------------------------------------ | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.WorkspaceBuild](schemas.md#codersdkworkspacebuild) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. diff --git a/docs/api/schemas.md b/docs/api/schemas.md index 843ed32642484..400a72292f70a 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -513,6 +513,47 @@ CreateParameterRequest is a structure used to create a new parameter value for a | `resource_type` | `api_key` | | `resource_type` | `group` | +## codersdk.CreateWorkspaceBuildRequest + +```json +{ + "dry_run": true, + "orphan": true, + "parameter_values": [ + { + "copy_from_parameter": "string", + "destination_scheme": "none", + "name": "string", + "source_scheme": "none", + "source_value": "string" + } + ], + "state": [0], + "template_version_id": "string", + "transition": "create" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| --------------------- | --------------------------------------------------------------------------- | -------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `dry_run` | boolean | false | | | +| `orphan` | boolean | false | | Orphan may be set for the Destroy transition. | +| `parameter_values` | array of [codersdk.CreateParameterRequest](#codersdkcreateparameterrequest) | false | | Parameter values are optional. It will write params to the 'workspace' scope. This will overwrite any existing parameters with the same name. This will not delete old params not included in this list. | +| `state` | array of integer | false | | | +| `template_version_id` | string | false | | | +| `transition` | string | true | | | + +#### Enumerated Values + +| Property | Value | +| ------------ | -------- | +| `transition` | `create` | +| `transition` | `start` | +| `transition` | `stop` | +| `transition` | `delete` | + ## codersdk.DERP ```json From 250982a0899aa846c1a0463f23b1bea0dc5d98b2 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Tue, 3 Jan 2023 12:18:39 +0100 Subject: [PATCH 10/36] templates.go, templateversions.go --- coderd/apidoc/docs.go | 254 ++++++++++++++++++++++++- coderd/apidoc/swagger.json | 231 ++++++++++++++++++++++- coderd/templates.go | 8 + coderd/templateversions.go | 27 +++ codersdk/templates.go | 1 + codersdk/templateversions.go | 10 +- codersdk/users.go | 18 +- docs/api/audit.md | 12 +- docs/api/schemas.md | 151 +++++++++++++-- docs/api/templates.md | 353 +++++++++++++++++++++++++++++++++++ 10 files changed, 1015 insertions(+), 50 deletions(-) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 0984d5eb2ccef..01007fab40c5a 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -808,6 +808,169 @@ const docTemplate = `{ } } }, + "/templates/{id}/daus": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Get template DAUs by ID", + "operationId": "get-template-daus-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.TemplateDAUsResponse" + } + } + } + } + }, + "/templates/{id}/versions": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "List template versions by template ID", + "operationId": "list-template-versions-by-template-ID", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.TemplateVersion" + } + } + } + } + }, + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Update active template version by template ID", + "operationId": "update-active-template-version-by-template-ID", + "parameters": [ + { + "description": "Modified template version", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateActiveTemplateVersion" + } + }, + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, + "/templates/{id}/versions/{name}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Get template version by template ID and name", + "operationId": "get-template-version-by-template-id-and-name", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Template name", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.TemplateVersion" + } + } + } + } + } + }, "/updatecheck": { "get": { "produces": [ @@ -2250,6 +2413,17 @@ const docTemplate = `{ } } }, + "codersdk.DAUEntry": { + "type": "object", + "properties": { + "amount": { + "type": "integer" + }, + "date": { + "type": "string" + } + } + }, "codersdk.DERP": { "type": "object", "properties": { @@ -3100,6 +3274,54 @@ const docTemplate = `{ "$ref": "#/definitions/codersdk.TransitionStats" } }, + "codersdk.TemplateDAUsResponse": { + "type": "object", + "properties": { + "entries": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.DAUEntry" + } + } + } + }, + "codersdk.TemplateVersion": { + "type": "object", + "properties": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "created_by": { + "$ref": "#/definitions/codersdk.User" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "job": { + "$ref": "#/definitions/codersdk.ProvisionerJob" + }, + "name": { + "type": "string" + }, + "organization_id": { + "type": "string", + "format": "uuid" + }, + "readme": { + "type": "string" + }, + "template_id": { + "type": "string", + "format": "uuid" + }, + "updated_at": { + "type": "string", + "format": "date-time" + } + } + }, "codersdk.TraceConfig": { "type": "object", "properties": { @@ -3127,6 +3349,17 @@ const docTemplate = `{ } } }, + "codersdk.UpdateActiveTemplateVersion": { + "type": "object", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "string" + } + } + }, "codersdk.UpdateCheckResponse": { "type": "object", "properties": { @@ -3186,24 +3419,29 @@ const docTemplate = `{ ], "properties": { "avatar_url": { - "type": "string" + "type": "string", + "format": "uri" }, "created_at": { - "type": "string" + "type": "string", + "format": "date-time" }, "email": { "type": "string" }, "id": { - "type": "string" + "type": "string", + "format": "uuid" }, "last_seen_at": { - "type": "string" + "type": "string", + "format": "date-time" }, "organization_ids": { "type": "array", "items": { - "type": "string" + "type": "string", + "format": "uuid" } }, "roles": { @@ -3213,7 +3451,11 @@ const docTemplate = `{ } }, "status": { - "type": "string" + "type": "string", + "enum": [ + "active", + "suspended" + ] }, "username": { "type": "string" diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 0dc03ac3ddd8f..46c1c2e2ef8b3 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -698,6 +698,151 @@ } } }, + "/templates/{id}/daus": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get template DAUs by ID", + "operationId": "get-template-daus-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.TemplateDAUsResponse" + } + } + } + } + }, + "/templates/{id}/versions": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "List template versions by template ID", + "operationId": "list-template-versions-by-template-ID", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.TemplateVersion" + } + } + } + } + }, + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Update active template version by template ID", + "operationId": "update-active-template-version-by-template-ID", + "parameters": [ + { + "description": "Modified template version", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateActiveTemplateVersion" + } + }, + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, + "/templates/{id}/versions/{name}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get template version by template ID and name", + "operationId": "get-template-version-by-template-id-and-name", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Template name", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.TemplateVersion" + } + } + } + } + } + }, "/updatecheck": { "get": { "produces": ["application/json"], @@ -1983,6 +2128,17 @@ } } }, + "codersdk.DAUEntry": { + "type": "object", + "properties": { + "amount": { + "type": "integer" + }, + "date": { + "type": "string" + } + } + }, "codersdk.DERP": { "type": "object", "properties": { @@ -2812,6 +2968,54 @@ "$ref": "#/definitions/codersdk.TransitionStats" } }, + "codersdk.TemplateDAUsResponse": { + "type": "object", + "properties": { + "entries": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.DAUEntry" + } + } + } + }, + "codersdk.TemplateVersion": { + "type": "object", + "properties": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "created_by": { + "$ref": "#/definitions/codersdk.User" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "job": { + "$ref": "#/definitions/codersdk.ProvisionerJob" + }, + "name": { + "type": "string" + }, + "organization_id": { + "type": "string", + "format": "uuid" + }, + "readme": { + "type": "string" + }, + "template_id": { + "type": "string", + "format": "uuid" + }, + "updated_at": { + "type": "string", + "format": "date-time" + } + } + }, "codersdk.TraceConfig": { "type": "object", "properties": { @@ -2839,6 +3043,15 @@ } } }, + "codersdk.UpdateActiveTemplateVersion": { + "type": "object", + "required": ["id"], + "properties": { + "id": { + "type": "string" + } + } + }, "codersdk.UpdateCheckResponse": { "type": "object", "properties": { @@ -2893,24 +3106,29 @@ "required": ["created_at", "email", "id", "username"], "properties": { "avatar_url": { - "type": "string" + "type": "string", + "format": "uri" }, "created_at": { - "type": "string" + "type": "string", + "format": "date-time" }, "email": { "type": "string" }, "id": { - "type": "string" + "type": "string", + "format": "uuid" }, "last_seen_at": { - "type": "string" + "type": "string", + "format": "date-time" }, "organization_ids": { "type": "array", "items": { - "type": "string" + "type": "string", + "format": "uuid" } }, "roles": { @@ -2920,7 +3138,8 @@ } }, "status": { - "type": "string" + "type": "string", + "enum": ["active", "suspended"] }, "username": { "type": "string" diff --git a/coderd/templates.go b/coderd/templates.go index 662a3069683c7..a7680355ee05d 100644 --- a/coderd/templates.go +++ b/coderd/templates.go @@ -599,6 +599,14 @@ func (api *API) patchTemplateMeta(rw http.ResponseWriter, r *http.Request) { httpapi.Write(ctx, rw, http.StatusOK, api.convertTemplate(updated, count, createdByNameMap[updated.ID.String()])) } +// @Summary Get template DAUs by ID +// @ID get-template-daus-by-id +// @Security CoderSessionToken +// @Produce json +// @Tags Templates +// @Param id path string true "Template ID" format(uuid) +// @Success 200 {object} codersdk.TemplateDAUsResponse +// @Router /templates/{id}/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 070500a26d8c9..94285d5364499 100644 --- a/coderd/templateversions.go +++ b/coderd/templateversions.go @@ -454,6 +454,14 @@ func (api *API) fetchTemplateVersionDryRunJob(rw http.ResponseWriter, r *http.Re return job, true } +// @Summary 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) +// @Success 200 {array} codersdk.TemplateVersion +// @Router /templates/{id}/versions [get] func (api *API) templateVersionsByTemplate(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() template := httpmw.TemplateParam(r) @@ -551,6 +559,15 @@ func (api *API) templateVersionsByTemplate(rw http.ResponseWriter, r *http.Reque httpapi.Write(ctx, rw, http.StatusOK, apiVersions) } +// @Summary Get template version by template ID and name +// @ID get-template-version-by-template-id-and-name +// @Security CoderSessionToken +// @Produce json +// @Tags Templates +// @Param id path string true "Template ID" format(uuid) +// @Param name path string true "Template name" +// @Success 200 {array} codersdk.TemplateVersion +// @Router /templates/{id}/versions/{name} [get] func (api *API) templateVersionByName(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() template := httpmw.TemplateParam(r) @@ -708,6 +725,16 @@ func (api *API) previousTemplateVersionByOrganizationAndName(rw http.ResponseWri httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(previousTemplateVersion, convertProvisionerJob(job), user)) } +// @Summary 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) +// @Success 200 {object} codersdk.Response +// @Router /templates/{id}/versions [patch] func (api *API) patchActiveTemplateVersion(rw http.ResponseWriter, r *http.Request) { var ( ctx = r.Context() diff --git a/codersdk/templates.go b/codersdk/templates.go index 3e066beb8bf7f..ee14775430005 100644 --- a/codersdk/templates.go +++ b/codersdk/templates.go @@ -214,6 +214,7 @@ type DAUEntry struct { Amount int `json:"amount"` } +// TemplateDAUsResponse contains statistics of daily active users of the template. type TemplateDAUsResponse struct { Entries []DAUEntry `json:"entries"` } diff --git a/codersdk/templateversions.go b/codersdk/templateversions.go index b9ea141f50654..1be7881ba5ae2 100644 --- a/codersdk/templateversions.go +++ b/codersdk/templateversions.go @@ -13,11 +13,11 @@ import ( // TemplateVersion represents a single version of a template. type TemplateVersion struct { - ID uuid.UUID `json:"id"` - TemplateID *uuid.UUID `json:"template_id,omitempty"` - OrganizationID uuid.UUID `json:"organization_id,omitempty"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + ID uuid.UUID `json:"id" format:"uuid"` + TemplateID *uuid.UUID `json:"template_id,omitempty" format:"uuid"` + OrganizationID uuid.UUID `json:"organization_id,omitempty" format:"uuid"` + CreatedAt time.Time `json:"created_at" format:"date-time"` + UpdatedAt time.Time `json:"updated_at" format:"date-time"` Name string `json:"name"` Job ProvisionerJob `json:"job"` Readme string `json:"readme"` diff --git a/codersdk/users.go b/codersdk/users.go index 6561c506fee0b..4b1f24afac933 100644 --- a/codersdk/users.go +++ b/codersdk/users.go @@ -35,16 +35,16 @@ type UsersRequest struct { // User represents a user in Coder. type User struct { - ID uuid.UUID `json:"id" validate:"required" table:"id"` + ID uuid.UUID `json:"id" validate:"required" table:"id" format:"uuid"` Username string `json:"username" validate:"required" table:"username"` Email string `json:"email" validate:"required" table:"email"` - CreatedAt time.Time `json:"created_at" validate:"required" table:"created at"` - LastSeenAt time.Time `json:"last_seen_at"` + CreatedAt time.Time `json:"created_at" validate:"required" table:"created at" format:"date-time"` + LastSeenAt time.Time `json:"last_seen_at" format:"date-time"` - Status UserStatus `json:"status" table:"status"` - OrganizationIDs []uuid.UUID `json:"organization_ids"` + Status UserStatus `json:"status" table:"status" enums:"active,suspended"` + OrganizationIDs []uuid.UUID `json:"organization_ids" format:"uuid"` Roles []Role `json:"roles"` - AvatarURL string `json:"avatar_url"` + AvatarURL string `json:"avatar_url" format:"uri"` } type GetUsersResponse struct { @@ -61,15 +61,15 @@ type CreateFirstUserRequest struct { // CreateFirstUserResponse contains IDs for newly created user info. type CreateFirstUserResponse struct { - UserID uuid.UUID `json:"user_id"` - OrganizationID uuid.UUID `json:"organization_id"` + UserID uuid.UUID `json:"user_id" format:"uuid"` + OrganizationID uuid.UUID `json:"organization_id" format:"uuid"` } type CreateUserRequest struct { Email string `json:"email" validate:"required,email"` Username string `json:"username" validate:"required,username"` Password string `json:"password" validate:"required"` - OrganizationID uuid.UUID `json:"organization_id" validate:"required"` + OrganizationID uuid.UUID `json:"organization_id" validate:"required" format:"uuid"` } type UpdateUserProfileRequest struct { diff --git a/docs/api/audit.md b/docs/api/audit.md index 8b3946c715665..d92f7233c9208 100644 --- a/docs/api/audit.md +++ b/docs/api/audit.md @@ -60,19 +60,19 @@ curl -X GET http://coder-server:8080/api/v2/audit?q=string \ "status_code": 0, "time": "string", "user": { - "avatar_url": "string", - "created_at": "string", + "avatar_url": "http://example.com", + "created_at": "2019-08-24T14:15:22Z", "email": "string", - "id": "string", - "last_seen_at": "string", - "organization_ids": ["string"], + "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": "string", + "status": "active", "username": "string" }, "user_agent": "string" diff --git a/docs/api/schemas.md b/docs/api/schemas.md index 400a72292f70a..f9197ba8f1583 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -163,19 +163,19 @@ "status_code": 0, "time": "string", "user": { - "avatar_url": "string", - "created_at": "string", + "avatar_url": "http://example.com", + "created_at": "2019-08-24T14:15:22Z", "email": "string", - "id": "string", - "last_seen_at": "string", - "organization_ids": ["string"], + "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": "string", + "status": "active", "username": "string" }, "user_agent": "string" @@ -239,19 +239,19 @@ "status_code": 0, "time": "string", "user": { - "avatar_url": "string", - "created_at": "string", + "avatar_url": "http://example.com", + "created_at": "2019-08-24T14:15:22Z", "email": "string", - "id": "string", - "last_seen_at": "string", - "organization_ids": ["string"], + "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": "string", + "status": "active", "username": "string" }, "user_agent": "string" @@ -554,6 +554,22 @@ CreateParameterRequest is a structure used to create a new parameter value for a | `transition` | `stop` | | `transition` | `delete` | +## codersdk.DAUEntry + +```json +{ + "amount": 0, + "date": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| -------- | ------- | -------- | ------------ | ----------- | +| `amount` | integer | false | | | +| `date` | string | false | | | + ## codersdk.DERP ```json @@ -2854,6 +2870,84 @@ Parameter represents a set value for the scope. | ---------------- | ---------------------------------------------------- | -------- | ------------ | ----------- | | `[any property]` | [codersdk.TransitionStats](#codersdktransitionstats) | false | | | +## codersdk.TemplateDAUsResponse + +```json +{ + "entries": [ + { + "amount": 0, + "date": "string" + } + ] +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| --------- | ----------------------------------------------- | -------- | ------------ | ----------- | +| `entries` | array of [codersdk.DAUEntry](#codersdkdauentry) | false | | | + +## codersdk.TemplateVersion + +```json +{ + "created_at": "2019-08-24T14:15:22Z", + "created_by": { + "avatar_url": "http://example.com", + "created_at": "2019-08-24T14:15:22Z", + "email": "string", + "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" + }, + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "job": { + "canceled_at": "2019-08-24T14:15:22Z", + "completed_at": "2019-08-24T14:15:22Z", + "created_at": "2019-08-24T14:15:22Z", + "error": "string", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" + }, + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "readme": "string", + "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", + "updated_at": "2019-08-24T14:15:22Z" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ----------------- | -------------------------------------------------- | -------- | ------------ | ----------- | +| `created_at` | string | false | | | +| `created_by` | [codersdk.User](#codersdkuser) | false | | | +| `id` | string | false | | | +| `job` | [codersdk.ProvisionerJob](#codersdkprovisionerjob) | false | | | +| `name` | string | false | | | +| `organization_id` | string | false | | | +| `readme` | string | false | | | +| `template_id` | string | false | | | +| `updated_at` | string | false | | | + ## codersdk.TraceConfig ```json @@ -2918,6 +3012,20 @@ Parameter represents a set value for the scope. | `p50` | integer | false | | | | `p95` | integer | false | | | +## codersdk.UpdateActiveTemplateVersion + +```json +{ + "id": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ---- | ------ | -------- | ------------ | ----------- | +| `id` | string | true | | | + ## codersdk.UpdateCheckResponse ```json @@ -2996,19 +3104,19 @@ Parameter represents a set value for the scope. ```json { - "avatar_url": "string", - "created_at": "string", + "avatar_url": "http://example.com", + "created_at": "2019-08-24T14:15:22Z", "email": "string", - "id": "string", - "last_seen_at": "string", - "organization_ids": ["string"], + "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": "string", + "status": "active", "username": "string" } ``` @@ -3027,6 +3135,13 @@ Parameter represents a set value for the scope. | `status` | string | false | | | | `username` | string | true | | | +#### Enumerated Values + +| Property | Value | +| -------- | ----------- | +| `status` | `active` | +| `status` | `suspended` | + ## codersdk.ValidationError ```json diff --git a/docs/api/templates.md b/docs/api/templates.md index 0cde6eaef5926..997383746bfb9 100644 --- a/docs/api/templates.md +++ b/docs/api/templates.md @@ -411,3 +411,356 @@ curl -X PATCH http://coder-server:8080/api/v2/templates/{id} \ | 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.Template](schemas.md#codersdktemplate) | To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Get template DAUs by ID + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/templates/{id}/daus \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /templates/{id}/daus` + +### Parameters + +| Name | In | Type | Required | Description | +| ---- | ---- | ------------ | -------- | ----------- | +| `id` | path | string(uuid) | true | Template ID | + +### Example responses + +> 200 Response + +```json +{ + "entries": [ + { + "amount": 0, + "date": "string" + } + ] +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ------------------------------------------------------------------------ | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.TemplateDAUsResponse](schemas.md#codersdktemplatedausresponse) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## List template versions by template ID + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/templates/{id}/versions \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /templates/{id}/versions` + +### Parameters + +| Name | In | Type | Required | Description | +| ---- | ---- | ------------ | -------- | ----------- | +| `id` | path | string(uuid) | true | Template ID | + +### Example responses + +> 200 Response + +```json +[ + { + "created_at": "2019-08-24T14:15:22Z", + "created_by": { + "avatar_url": "http://example.com", + "created_at": "2019-08-24T14:15:22Z", + "email": "string", + "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" + }, + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "job": { + "canceled_at": "2019-08-24T14:15:22Z", + "completed_at": "2019-08-24T14:15:22Z", + "created_at": "2019-08-24T14:15:22Z", + "error": "string", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" + }, + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "readme": "string", + "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", + "updated_at": "2019-08-24T14:15:22Z" + } +] +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ----------------------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | array of [codersdk.TemplateVersion](schemas.md#codersdktemplateversion) | + +

Response Schema

+ +Status Code **200** + +| Name | Type | Required | Restrictions | Description | +| --------------------- | ------------------------- | -------- | ------------ | ----------- | +| `[array item]` | array | false | | | +| `» created_at` | string | false | | | +| `» created_by` | `codersdk.User` | false | | | +| `»» avatar_url` | string | false | | | +| `»» created_at` | string | true | | | +| `»» email` | string | true | | | +| `»» id` | string | true | | | +| `»» last_seen_at` | string | false | | | +| `»» organization_ids` | array | false | | | +| `»» roles` | array | false | | | +| `»»» display_name` | string | false | | | +| `»»» name` | string | false | | | +| `»» status` | string | false | | | +| `»» username` | string | true | | | +| `» id` | string | false | | | +| `» job` | `codersdk.ProvisionerJob` | false | | | +| `»» canceled_at` | string | false | | | +| `»» completed_at` | string | false | | | +| `»» created_at` | string | false | | | +| `»» error` | string | false | | | +| `»» file_id` | string | false | | | +| `»» id` | string | false | | | +| `»» started_at` | string | false | | | +| `»» status` | string | false | | | +| `»» tags` | object | false | | | +| `»»» [any property]` | string | false | | | +| `»» worker_id` | string | false | | | +| `» name` | string | false | | | +| `» organization_id` | string | false | | | +| `» readme` | string | false | | | +| `» template_id` | string | false | | | +| `» updated_at` | string | false | | | + +#### Enumerated Values + +| Property | Value | +| -------- | ----------- | +| `status` | `active` | +| `status` | `suspended` | +| `status` | `pending` | +| `status` | `running` | +| `status` | `succeeded` | +| `status` | `canceling` | +| `status` | `canceled` | +| `status` | `failed` | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Update active template version by template ID + +### Code samples + +```shell +# Example request using curl +curl -X PATCH http://coder-server:8080/api/v2/templates/{id}/versions \ + -H 'Content-Type: application/json' \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`PATCH /templates/{id}/versions` + +> Body parameter + +```json +{ + "id": "string" +} +``` + +### Parameters + +| Name | In | Type | Required | Description | +| ------ | ---- | -------------------------------------------------------------------------------------- | -------- | ------------------------- | +| `id` | path | string(uuid) | true | Template ID | +| `body` | body | [codersdk.UpdateActiveTemplateVersion](schemas.md#codersdkupdateactivetemplateversion) | true | Modified template version | + +### Example responses + +> 200 Response + +```json +{ + "detail": "string", + "message": "string", + "validations": [ + { + "detail": "string", + "field": "string" + } + ] +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ------------------------------------------------ | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.Response](schemas.md#codersdkresponse) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Get template version by template ID and name + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/templates/{id}/versions/{name} \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /templates/{id}/versions/{name}` + +### Parameters + +| Name | In | Type | Required | Description | +| ------ | ---- | ------------ | -------- | ------------- | +| `id` | path | string(uuid) | true | Template ID | +| `name` | path | string | true | Template name | + +### Example responses + +> 200 Response + +```json +[ + { + "created_at": "2019-08-24T14:15:22Z", + "created_by": { + "avatar_url": "http://example.com", + "created_at": "2019-08-24T14:15:22Z", + "email": "string", + "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" + }, + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "job": { + "canceled_at": "2019-08-24T14:15:22Z", + "completed_at": "2019-08-24T14:15:22Z", + "created_at": "2019-08-24T14:15:22Z", + "error": "string", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" + }, + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "readme": "string", + "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", + "updated_at": "2019-08-24T14:15:22Z" + } +] +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ----------------------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | array of [codersdk.TemplateVersion](schemas.md#codersdktemplateversion) | + +

Response Schema

+ +Status Code **200** + +| Name | Type | Required | Restrictions | Description | +| --------------------- | ------------------------- | -------- | ------------ | ----------- | +| `[array item]` | array | false | | | +| `» created_at` | string | false | | | +| `» created_by` | `codersdk.User` | false | | | +| `»» avatar_url` | string | false | | | +| `»» created_at` | string | true | | | +| `»» email` | string | true | | | +| `»» id` | string | true | | | +| `»» last_seen_at` | string | false | | | +| `»» organization_ids` | array | false | | | +| `»» roles` | array | false | | | +| `»»» display_name` | string | false | | | +| `»»» name` | string | false | | | +| `»» status` | string | false | | | +| `»» username` | string | true | | | +| `» id` | string | false | | | +| `» job` | `codersdk.ProvisionerJob` | false | | | +| `»» canceled_at` | string | false | | | +| `»» completed_at` | string | false | | | +| `»» created_at` | string | false | | | +| `»» error` | string | false | | | +| `»» file_id` | string | false | | | +| `»» id` | string | false | | | +| `»» started_at` | string | false | | | +| `»» status` | string | false | | | +| `»» tags` | object | false | | | +| `»»» [any property]` | string | false | | | +| `»» worker_id` | string | false | | | +| `» name` | string | false | | | +| `» organization_id` | string | false | | | +| `» readme` | string | false | | | +| `» template_id` | string | false | | | +| `» updated_at` | string | false | | | + +#### Enumerated Values + +| Property | Value | +| -------- | ----------- | +| `status` | `active` | +| `status` | `suspended` | +| `status` | `pending` | +| `status` | `running` | +| `status` | `succeeded` | +| `status` | `canceling` | +| `status` | `canceled` | +| `status` | `failed` | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. From ff622a7ba085200e45feee07c69dc670392a7083 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Tue, 3 Jan 2023 12:39:05 +0100 Subject: [PATCH 11/36] templateversion.go in progress --- coderd/apidoc/docs.go | 148 ++++++++++++++++++++++++++++++++- coderd/apidoc/swagger.json | 133 ++++++++++++++++++++++++++++- coderd/templateversions.go | 16 ++++ codersdk/parameters.go | 14 ++-- docs/api/builds.md | 2 +- docs/api/parameters.md | 2 +- docs/api/schemas.md | 62 +++++++++++++- docs/api/templates.md | 166 ++++++++++++++++++++++++++++++++++++- 8 files changed, 528 insertions(+), 15 deletions(-) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 01007fab40c5a..2cb3cd9fd2125 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -971,6 +971,79 @@ const docTemplate = `{ } } }, + "/templateversions/{id}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Get template version by ID", + "operationId": "get-template-version-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.TemplateVersion" + } + } + } + } + }, + "/templateversions/{id}/schema": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Get template version schema by template version ID", + "operationId": "get-template-version-schema-by-template-version-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.ParameterSchema" + } + } + } + } + } + }, "/updatecheck": { "get": { "produces": [ @@ -2270,7 +2343,8 @@ const docTemplate = `{ "properties": { "copy_from_parameter": { "description": "CloneID allows copying the value of another parameter.\nThe other param must be related to the same template_id for this to\nsucceed.\nNo other fields are required if using this, as all fields will be copied\nfrom the other parameter.", - "type": "string" + "type": "string", + "format": "uuid" }, "destination_scheme": { "type": "string", @@ -2964,6 +3038,78 @@ const docTemplate = `{ } } }, + "codersdk.ParameterSchema": { + "type": "object", + "properties": { + "allow_override_destination": { + "type": "boolean" + }, + "allow_override_source": { + "type": "boolean" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "default_destination_scheme": { + "type": "string", + "enum": [ + "none", + "environment_variable", + "provisioner_variable" + ] + }, + "default_refresh": { + "type": "string" + }, + "default_source_scheme": { + "type": "string", + "enum": [ + "none", + "data" + ] + }, + "default_source_value": { + "type": "string" + }, + "description": { + "type": "string" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "job_id": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "redisplay_value": { + "type": "boolean" + }, + "validation_condition": { + "type": "string" + }, + "validation_contains": { + "description": "This is a special array of items provided if the validation condition\nexplicitly states the value must be one of a set.", + "type": "array", + "items": { + "type": "string" + } + }, + "validation_error": { + "type": "string" + }, + "validation_type_system": { + "type": "string" + }, + "validation_value_type": { + "type": "string" + } + } + }, "codersdk.PostWorkspaceAgentVersionRequest": { "type": "object", "properties": { diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 46c1c2e2ef8b3..991e8b8b69a16 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -843,6 +843,71 @@ } } }, + "/templateversions/{id}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get template version by ID", + "operationId": "get-template-version-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.TemplateVersion" + } + } + } + } + }, + "/templateversions/{id}/schema": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get template version schema by template version ID", + "operationId": "get-template-version-schema-by-template-version-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.ParameterSchema" + } + } + } + } + } + }, "/updatecheck": { "get": { "produces": ["application/json"], @@ -2008,7 +2073,8 @@ "properties": { "copy_from_parameter": { "description": "CloneID allows copying the value of another parameter.\nThe other param must be related to the same template_id for this to\nsucceed.\nNo other fields are required if using this, as all fields will be copied\nfrom the other parameter.", - "type": "string" + "type": "string", + "format": "uuid" }, "destination_scheme": { "type": "string", @@ -2666,6 +2732,71 @@ } } }, + "codersdk.ParameterSchema": { + "type": "object", + "properties": { + "allow_override_destination": { + "type": "boolean" + }, + "allow_override_source": { + "type": "boolean" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "default_destination_scheme": { + "type": "string", + "enum": ["none", "environment_variable", "provisioner_variable"] + }, + "default_refresh": { + "type": "string" + }, + "default_source_scheme": { + "type": "string", + "enum": ["none", "data"] + }, + "default_source_value": { + "type": "string" + }, + "description": { + "type": "string" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "job_id": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "redisplay_value": { + "type": "boolean" + }, + "validation_condition": { + "type": "string" + }, + "validation_contains": { + "description": "This is a special array of items provided if the validation condition\nexplicitly states the value must be one of a set.", + "type": "array", + "items": { + "type": "string" + } + }, + "validation_error": { + "type": "string" + }, + "validation_type_system": { + "type": "string" + }, + "validation_value_type": { + "type": "string" + } + } + }, "codersdk.PostWorkspaceAgentVersionRequest": { "type": "object", "properties": { diff --git a/coderd/templateversions.go b/coderd/templateversions.go index 94285d5364499..9e43040526895 100644 --- a/coderd/templateversions.go +++ b/coderd/templateversions.go @@ -28,6 +28,14 @@ import ( "github.com/coder/coder/examples" ) +// @Summary Get template version by ID +// @ID get-template-version-by-id +// @Security CoderSessionToken +// @Produce json +// @Tags Templates +// @Param id path string true "Template version ID" format(uuid) +// @Success 200 {object} codersdk.TemplateVersion +// @Router /templateversions/{id} [get] func (api *API) templateVersion(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() var ( @@ -116,6 +124,14 @@ func (api *API) patchCancelTemplateVersion(rw http.ResponseWriter, r *http.Reque }) } +// @Summary Get template version schema by template version ID +// @ID get-template-version-schema-by-template-version-id +// @Security CoderSessionToken +// @Produce json +// @Tags Templates +// @Param id path string true "Template version ID" format(uuid) +// @Success 200 {array} codersdk.ParameterSchema +// @Router /templateversions/{id}/schema [get] func (api *API) templateVersionSchema(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() var ( diff --git a/codersdk/parameters.go b/codersdk/parameters.go index 92717e55e1651..086e88817a415 100644 --- a/codersdk/parameters.go +++ b/codersdk/parameters.go @@ -44,7 +44,7 @@ const ( type ComputedParameter struct { Parameter SourceValue string `json:"source_value"` - SchemaID uuid.UUID `json:"schema_id"` + SchemaID uuid.UUID `json:"schema_id" format:"uuid"` DefaultSourceValue bool `json:"default_source_value"` } @@ -63,15 +63,15 @@ type Parameter struct { } type ParameterSchema struct { - ID uuid.UUID `json:"id"` - CreatedAt time.Time `json:"created_at"` - JobID uuid.UUID `json:"job_id"` + ID uuid.UUID `json:"id" format:"uuid"` + CreatedAt time.Time `json:"created_at" format:"date-time"` + JobID uuid.UUID `json:"job_id" format:"uuid"` Name string `json:"name"` Description string `json:"description"` - DefaultSourceScheme ParameterSourceScheme `json:"default_source_scheme"` + DefaultSourceScheme ParameterSourceScheme `json:"default_source_scheme" enums:"none,data"` DefaultSourceValue string `json:"default_source_value"` AllowOverrideSource bool `json:"allow_override_source"` - DefaultDestinationScheme ParameterDestinationScheme `json:"default_destination_scheme"` + DefaultDestinationScheme ParameterDestinationScheme `json:"default_destination_scheme" enums:"none,environment_variable,provisioner_variable"` AllowOverrideDestination bool `json:"allow_override_destination"` DefaultRefresh string `json:"default_refresh"` RedisplayValue bool `json:"redisplay_value"` @@ -94,7 +94,7 @@ type CreateParameterRequest struct { // succeed. // No other fields are required if using this, as all fields will be copied // from the other parameter. - CloneID uuid.UUID `json:"copy_from_parameter,omitempty" validate:""` + CloneID uuid.UUID `json:"copy_from_parameter,omitempty" validate:"" format:"uuid"` Name string `json:"name" validate:"required"` SourceValue string `json:"source_value" validate:"required"` diff --git a/docs/api/builds.md b/docs/api/builds.md index 2eea39745c4ea..25e777566de55 100644 --- a/docs/api/builds.md +++ b/docs/api/builds.md @@ -881,7 +881,7 @@ curl -X POST http://coder-server:8080/api/v2/workspaces/{id}/builds \ "orphan": true, "parameter_values": [ { - "copy_from_parameter": "string", + "copy_from_parameter": "000e07d6-021d-446c-be14-48a9c20bca0b", "destination_scheme": "none", "name": "string", "source_scheme": "none", diff --git a/docs/api/parameters.md b/docs/api/parameters.md index 5b035413f09b0..5b0ca38fc1d30 100644 --- a/docs/api/parameters.md +++ b/docs/api/parameters.md @@ -104,7 +104,7 @@ curl -X POST http://coder-server:8080/api/v2/parameters/{scope}/{id} \ ```json { - "copy_from_parameter": "string", + "copy_from_parameter": "000e07d6-021d-446c-be14-48a9c20bca0b", "destination_scheme": "none", "name": "string", "source_scheme": "none", diff --git a/docs/api/schemas.md b/docs/api/schemas.md index f9197ba8f1583..fd3966a20ac5d 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -407,7 +407,7 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in ```json { - "copy_from_parameter": "string", + "copy_from_parameter": "000e07d6-021d-446c-be14-48a9c20bca0b", "destination_scheme": "none", "name": "string", "source_scheme": "none", @@ -449,7 +449,7 @@ CreateParameterRequest is a structure used to create a new parameter value for a "name": "string", "parameter_values": [ { - "copy_from_parameter": "string", + "copy_from_parameter": "000e07d6-021d-446c-be14-48a9c20bca0b", "destination_scheme": "none", "name": "string", "source_scheme": "none", @@ -521,7 +521,7 @@ CreateParameterRequest is a structure used to create a new parameter value for a "orphan": true, "parameter_values": [ { - "copy_from_parameter": "string", + "copy_from_parameter": "000e07d6-021d-446c-be14-48a9c20bca0b", "destination_scheme": "none", "name": "string", "source_scheme": "none", @@ -2292,6 +2292,62 @@ Parameter represents a set value for the scope. | `source_scheme` | `none` | | `source_scheme` | `data` | +## codersdk.ParameterSchema + +```json +{ + "allow_override_destination": true, + "allow_override_source": true, + "created_at": "2019-08-24T14:15:22Z", + "default_destination_scheme": "none", + "default_refresh": "string", + "default_source_scheme": "none", + "default_source_value": "string", + "description": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f", + "name": "string", + "redisplay_value": true, + "validation_condition": "string", + "validation_contains": ["string"], + "validation_error": "string", + "validation_type_system": "string", + "validation_value_type": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ---------------------------- | --------------- | -------- | ------------ | ----------------------------------------------------------------------------------------------------------------------- | +| `allow_override_destination` | boolean | false | | | +| `allow_override_source` | boolean | false | | | +| `created_at` | string | false | | | +| `default_destination_scheme` | string | false | | | +| `default_refresh` | string | false | | | +| `default_source_scheme` | string | false | | | +| `default_source_value` | string | false | | | +| `description` | string | false | | | +| `id` | string | false | | | +| `job_id` | string | false | | | +| `name` | string | false | | | +| `redisplay_value` | boolean | false | | | +| `validation_condition` | string | false | | | +| `validation_contains` | array of string | false | | This is a special array of items provided if the validation condition explicitly states the value must be one of a set. | +| `validation_error` | string | false | | | +| `validation_type_system` | string | false | | | +| `validation_value_type` | string | false | | | + +#### Enumerated Values + +| Property | Value | +| ---------------------------- | ---------------------- | +| `default_destination_scheme` | `none` | +| `default_destination_scheme` | `environment_variable` | +| `default_destination_scheme` | `provisioner_variable` | +| `default_source_scheme` | `none` | +| `default_source_scheme` | `data` | + ## codersdk.PostWorkspaceAgentVersionRequest ```json diff --git a/docs/api/templates.md b/docs/api/templates.md index 997383746bfb9..d17f0e4ea0f1a 100644 --- a/docs/api/templates.md +++ b/docs/api/templates.md @@ -28,7 +28,7 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization-id}/tem "name": "string", "parameter_values": [ { - "copy_from_parameter": "string", + "copy_from_parameter": "000e07d6-021d-446c-be14-48a9c20bca0b", "destination_scheme": "none", "name": "string", "source_scheme": "none", @@ -764,3 +764,167 @@ Status Code **200** | `status` | `failed` | To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Get template version by ID + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/templateversions/{id} \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /templateversions/{id}` + +### Parameters + +| Name | In | Type | Required | Description | +| ---- | ---- | ------------ | -------- | ------------------- | +| `id` | path | string(uuid) | true | Template version ID | + +### Example responses + +> 200 Response + +```json +{ + "created_at": "2019-08-24T14:15:22Z", + "created_by": { + "avatar_url": "http://example.com", + "created_at": "2019-08-24T14:15:22Z", + "email": "string", + "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" + }, + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "job": { + "canceled_at": "2019-08-24T14:15:22Z", + "completed_at": "2019-08-24T14:15:22Z", + "created_at": "2019-08-24T14:15:22Z", + "error": "string", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" + }, + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "readme": "string", + "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", + "updated_at": "2019-08-24T14:15:22Z" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | -------------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.TemplateVersion](schemas.md#codersdktemplateversion) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Get template version schema by template version ID + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/templateversions/{id}/schema \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /templateversions/{id}/schema` + +### Parameters + +| Name | In | Type | Required | Description | +| ---- | ---- | ------------ | -------- | ------------------- | +| `id` | path | string(uuid) | true | Template version ID | + +### Example responses + +> 200 Response + +```json +[ + { + "allow_override_destination": true, + "allow_override_source": true, + "created_at": "2019-08-24T14:15:22Z", + "default_destination_scheme": "none", + "default_refresh": "string", + "default_source_scheme": "none", + "default_source_value": "string", + "description": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f", + "name": "string", + "redisplay_value": true, + "validation_condition": "string", + "validation_contains": ["string"], + "validation_error": "string", + "validation_type_system": "string", + "validation_value_type": "string" + } +] +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ----------------------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | array of [codersdk.ParameterSchema](schemas.md#codersdkparameterschema) | + +

Response Schema

+ +Status Code **200** + +| Name | Type | Required | Restrictions | Description | +| ------------------------------ | ------- | -------- | ------------ | -------------------------------------------------------------------------------------------------------------------------- | +| `[array item]` | array | false | | | +| `» allow_override_destination` | boolean | false | | | +| `» allow_override_source` | boolean | false | | | +| `» created_at` | string | false | | | +| `» default_destination_scheme` | string | false | | | +| `» default_refresh` | string | false | | | +| `» default_source_scheme` | string | false | | | +| `» default_source_value` | string | false | | | +| `» description` | string | false | | | +| `» id` | string | false | | | +| `» job_id` | string | false | | | +| `» name` | string | false | | | +| `» redisplay_value` | boolean | false | | | +| `» validation_condition` | string | false | | | +| `» validation_contains` | array | false | | This is a special array of items provided if the validation condition
explicitly states the value must be one of a set. | +| `» validation_error` | string | false | | | +| `» validation_type_system` | string | false | | | +| `» validation_value_type` | string | false | | | + +#### Enumerated Values + +| Property | Value | +| ---------------------------- | ---------------------- | +| `default_destination_scheme` | `none` | +| `default_destination_scheme` | `environment_variable` | +| `default_destination_scheme` | `provisioner_variable` | +| `default_source_scheme` | `none` | +| `default_source_scheme` | `data` | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. From 9dd385cfa4d4ced395e306de35685dc5e8e2862f Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Tue, 3 Jan 2023 13:05:24 +0100 Subject: [PATCH 12/36] cancel --- coderd/apidoc/docs.go | 79 ++++++++++++++++++++++- coderd/apidoc/swagger.json | 75 +++++++++++++++++++++- coderd/coderd.go | 1 - coderd/templateversions.go | 16 +++++ docs/api/schemas.md | 34 ++++++++++ docs/api/templates.md | 124 ++++++++++++++++++++++--------------- 6 files changed, 271 insertions(+), 58 deletions(-) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 2cb3cd9fd2125..34b0996f10a74 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -1006,6 +1006,41 @@ const docTemplate = `{ } } }, + "/templateversions/{id}/cancel": { + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Cancel template version by ID", + "operationId": "cancel-template-version-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, "/templateversions/{id}/schema": { "get": { "security": [ @@ -1019,8 +1054,8 @@ const docTemplate = `{ "tags": [ "Templates" ], - "summary": "Get template version schema by template version ID", - "operationId": "get-template-version-schema-by-template-version-id", + "summary": "Get template version schema by ID", + "operationId": "get-template-version-schema-by-id", "parameters": [ { "type": "string", @@ -1037,7 +1072,7 @@ const docTemplate = `{ "schema": { "type": "array", "items": { - "$ref": "#/definitions/codersdk.ParameterSchema" + "$ref": "#/definitions/parameter.ComputedValue" } } } @@ -4057,6 +4092,44 @@ const docTemplate = `{ "netip.Addr": { "type": "object" }, + "parameter.ComputedValue": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "default_source_value": { + "type": "boolean" + }, + "destination_scheme": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "schema_id": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "scope_id": { + "type": "string" + }, + "source_scheme": { + "type": "string" + }, + "source_value": { + "type": "string" + }, + "updated_at": { + "type": "string" + } + } + }, "tailcfg.DERPMap": { "type": "object", "properties": { diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 991e8b8b69a16..ec759a22890dc 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -874,6 +874,37 @@ } } }, + "/templateversions/{id}/cancel": { + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Cancel template version by ID", + "operationId": "cancel-template-version-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, "/templateversions/{id}/schema": { "get": { "security": [ @@ -883,8 +914,8 @@ ], "produces": ["application/json"], "tags": ["Templates"], - "summary": "Get template version schema by template version ID", - "operationId": "get-template-version-schema-by-template-version-id", + "summary": "Get template version schema by ID", + "operationId": "get-template-version-schema-by-id", "parameters": [ { "type": "string", @@ -901,7 +932,7 @@ "schema": { "type": "array", "items": { - "$ref": "#/definitions/codersdk.ParameterSchema" + "$ref": "#/definitions/parameter.ComputedValue" } } } @@ -3702,6 +3733,44 @@ "netip.Addr": { "type": "object" }, + "parameter.ComputedValue": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "default_source_value": { + "type": "boolean" + }, + "destination_scheme": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "schema_id": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "scope_id": { + "type": "string" + }, + "source_scheme": { + "type": "string" + }, + "source_value": { + "type": "string" + }, + "updated_at": { + "type": "string" + } + } + }, "tailcfg.DERPMap": { "type": "object", "properties": { diff --git a/coderd/coderd.go b/coderd/coderd.go index f66bd82aa630b..51ccdced50442 100644 --- a/coderd/coderd.go +++ b/coderd/coderd.go @@ -409,7 +409,6 @@ func New(options *Options) *API { apiKeyMiddleware, httpmw.ExtractTemplateVersionParam(options.Database), ) - r.Get("/", api.templateVersion) r.Patch("/cancel", api.patchCancelTemplateVersion) r.Get("/schema", api.templateVersionSchema) diff --git a/coderd/templateversions.go b/coderd/templateversions.go index 9e43040526895..594d86e9c8888 100644 --- a/coderd/templateversions.go +++ b/coderd/templateversions.go @@ -69,6 +69,14 @@ func (api *API) templateVersion(rw http.ResponseWriter, r *http.Request) { httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(templateVersion, convertProvisionerJob(job), user)) } +// @Summary Cancel template version by ID +// @ID cancel-template-version-by-id +// @Security CoderSessionToken +// @Produce json +// @Tags Templates +// @Param id path string true "Template version ID" format(uuid) +// @Success 200 {object} codersdk.Response +// @Router /templateversions/{id}/cancel [patch] func (api *API) patchCancelTemplateVersion(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() var ( @@ -184,6 +192,14 @@ func (api *API) templateVersionSchema(rw http.ResponseWriter, r *http.Request) { httpapi.Write(ctx, rw, http.StatusOK, apiSchemas) } +// @Summary Get template version schema by ID +// @ID get-template-version-schema-by-id +// @Security CoderSessionToken +// @Produce json +// @Tags Templates +// @Param id path string true "Template version ID" format(uuid) +// @Success 200 {array} parameter.ComputedValue +// @Router /templateversions/{id}/schema [get] func (api *API) templateVersionParameters(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() var ( diff --git a/docs/api/schemas.md b/docs/api/schemas.md index fd3966a20ac5d..ab8bfa6a5fb3a 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -4061,6 +4061,40 @@ Parameter represents a set value for the scope. _None_ +## parameter.ComputedValue + +```json +{ + "created_at": "string", + "default_source_value": true, + "destination_scheme": "string", + "id": "string", + "name": "string", + "schema_id": "string", + "scope": "string", + "scope_id": "string", + "source_scheme": "string", + "source_value": "string", + "updated_at": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ---------------------- | ------- | -------- | ------------ | ----------- | +| `created_at` | string | false | | | +| `default_source_value` | boolean | false | | | +| `destination_scheme` | string | false | | | +| `id` | string | false | | | +| `name` | string | false | | | +| `schema_id` | string | false | | | +| `scope` | string | false | | | +| `scope_id` | string | false | | | +| `source_scheme` | string | false | | | +| `source_value` | string | false | | | +| `updated_at` | string | false | | | + ## tailcfg.DERPMap ```json diff --git a/docs/api/templates.md b/docs/api/templates.md index d17f0e4ea0f1a..b17668cda1b1a 100644 --- a/docs/api/templates.md +++ b/docs/api/templates.md @@ -839,7 +839,51 @@ curl -X GET http://coder-server:8080/api/v2/templateversions/{id} \ To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. -## Get template version schema by template version ID +## Cancel template version by ID + +### Code samples + +```shell +# Example request using curl +curl -X PATCH http://coder-server:8080/api/v2/templateversions/{id}/cancel \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`PATCH /templateversions/{id}/cancel` + +### Parameters + +| Name | In | Type | Required | Description | +| ---- | ---- | ------------ | -------- | ------------------- | +| `id` | path | string(uuid) | true | Template version ID | + +### Example responses + +> 200 Response + +```json +{ + "detail": "string", + "message": "string", + "validations": [ + { + "detail": "string", + "field": "string" + } + ] +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ------------------------------------------------ | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.Response](schemas.md#codersdkresponse) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Get template version schema by ID ### Code samples @@ -865,66 +909,44 @@ curl -X GET http://coder-server:8080/api/v2/templateversions/{id}/schema \ ```json [ { - "allow_override_destination": true, - "allow_override_source": true, - "created_at": "2019-08-24T14:15:22Z", - "default_destination_scheme": "none", - "default_refresh": "string", - "default_source_scheme": "none", - "default_source_value": "string", - "description": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f", + "created_at": "string", + "default_source_value": true, + "destination_scheme": "string", + "id": "string", "name": "string", - "redisplay_value": true, - "validation_condition": "string", - "validation_contains": ["string"], - "validation_error": "string", - "validation_type_system": "string", - "validation_value_type": "string" + "schema_id": "string", + "scope": "string", + "scope_id": "string", + "source_scheme": "string", + "source_value": "string", + "updated_at": "string" } ] ``` ### Responses -| Status | Meaning | Description | Schema | -| ------ | ------------------------------------------------------- | ----------- | ----------------------------------------------------------------------- | -| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | array of [codersdk.ParameterSchema](schemas.md#codersdkparameterschema) | +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | --------------------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | array of [parameter.ComputedValue](schemas.md#parametercomputedvalue) | -

Response Schema

+

Response Schema

Status Code **200** -| Name | Type | Required | Restrictions | Description | -| ------------------------------ | ------- | -------- | ------------ | -------------------------------------------------------------------------------------------------------------------------- | -| `[array item]` | array | false | | | -| `» allow_override_destination` | boolean | false | | | -| `» allow_override_source` | boolean | false | | | -| `» created_at` | string | false | | | -| `» default_destination_scheme` | string | false | | | -| `» default_refresh` | string | false | | | -| `» default_source_scheme` | string | false | | | -| `» default_source_value` | string | false | | | -| `» description` | string | false | | | -| `» id` | string | false | | | -| `» job_id` | string | false | | | -| `» name` | string | false | | | -| `» redisplay_value` | boolean | false | | | -| `» validation_condition` | string | false | | | -| `» validation_contains` | array | false | | This is a special array of items provided if the validation condition
explicitly states the value must be one of a set. | -| `» validation_error` | string | false | | | -| `» validation_type_system` | string | false | | | -| `» validation_value_type` | string | false | | | - -#### Enumerated Values - -| Property | Value | -| ---------------------------- | ---------------------- | -| `default_destination_scheme` | `none` | -| `default_destination_scheme` | `environment_variable` | -| `default_destination_scheme` | `provisioner_variable` | -| `default_source_scheme` | `none` | -| `default_source_scheme` | `data` | +| Name | Type | Required | Restrictions | Description | +| ------------------------ | ------- | -------- | ------------ | ----------- | +| `[array item]` | array | false | | | +| `» created_at` | string | false | | | +| `» default_source_value` | boolean | false | | | +| `» destination_scheme` | string | false | | | +| `» id` | string | false | | | +| `» name` | string | false | | | +| `» schema_id` | string | false | | | +| `» scope` | string | false | | | +| `» scope_id` | string | false | | | +| `» source_scheme` | string | false | | | +| `» source_value` | string | false | | | +| `» updated_at` | string | false | | | To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. From f96351a3b2c68d024dea27a33b6a822dc98eadb6 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Tue, 3 Jan 2023 14:27:43 +0100 Subject: [PATCH 13/36] templateversions --- coderd/apidoc/docs.go | 308 +++++++++++++++++++++++ coderd/apidoc/swagger.json | 280 +++++++++++++++++++++ coderd/templateversions.go | 70 ++++++ docs/api/schemas.md | 24 ++ docs/api/templates.md | 489 +++++++++++++++++++++++++++++++++++++ 5 files changed, 1171 insertions(+) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 34b0996f10a74..a03103999f70d 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -1041,6 +1041,109 @@ const docTemplate = `{ } } }, + "/templateversions/{id}/dry-run": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Create template version dry-run", + "operationId": "create-template-version-dry-run", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Dry-run request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateTemplateVersionDryRunRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.ProvisionerJob" + } + } + } + } + }, + "/templateversions/{id}/resources": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Get template version logs by template version ID", + "operationId": "get-template-version-resources-by-template-version-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "integer", + "description": "Before Unix timestamp", + "name": "before", + "in": "query" + }, + { + "type": "integer", + "description": "After Unix timestamp", + "name": "after", + "in": "query" + }, + { + "type": "boolean", + "description": "Follow log stream", + "name": "follow", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.ProvisionerJobLog" + } + } + } + } + } + }, "/templateversions/{id}/schema": { "get": { "security": [ @@ -1079,6 +1182,197 @@ const docTemplate = `{ } } }, + "/templateversions/{templateversionid}/dry-run/{jobid}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Get template version dry-run by job ID", + "operationId": "get-template-version-dry-run-by-job-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversionid", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "Job ID", + "name": "jobid", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.ProvisionerJob" + } + } + } + } + }, + "/templateversions/{templateversionid}/dry-run/{jobid}/cancel": { + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Cancel template version dry-run by job ID", + "operationId": "cancel-template-version-dry-run-by-job-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, + "/templateversions/{templateversionid}/dry-run/{jobid}/logs": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Get template version dry-run logs by job ID", + "operationId": "get-template-version-dry-run-logs-by-job-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversionid", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "Job ID", + "name": "jobid", + "in": "path", + "required": true + }, + { + "type": "integer", + "description": "Before Unix timestamp", + "name": "before", + "in": "query" + }, + { + "type": "integer", + "description": "After Unix timestamp", + "name": "after", + "in": "query" + }, + { + "type": "boolean", + "description": "Follow log stream", + "name": "follow", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.ProvisionerJobLog" + } + } + } + } + } + }, + "/templateversions/{templateversionid}/dry-run/{jobid}/resources": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Get template version dry-run resources by job ID", + "operationId": "get-template-version-dry-run-resources-by-job-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversionid", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "Job ID", + "name": "jobid", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceResource" + } + } + } + } + } + }, "/updatecheck": { "get": { "produces": [ @@ -2447,6 +2741,20 @@ const docTemplate = `{ } } }, + "codersdk.CreateTemplateVersionDryRunRequest": { + "type": "object", + "properties": { + "parameter_values": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.CreateParameterRequest" + } + }, + "workspace_name": { + "type": "string" + } + } + }, "codersdk.CreateTestAuditLogRequest": { "type": "object", "properties": { diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index ec759a22890dc..fb79b44971a4c 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -905,6 +905,99 @@ } } }, + "/templateversions/{id}/dry-run": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Create template version dry-run", + "operationId": "create-template-version-dry-run", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Dry-run request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateTemplateVersionDryRunRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.ProvisionerJob" + } + } + } + } + }, + "/templateversions/{id}/resources": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get template version logs by template version ID", + "operationId": "get-template-version-resources-by-template-version-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "integer", + "description": "Before Unix timestamp", + "name": "before", + "in": "query" + }, + { + "type": "integer", + "description": "After Unix timestamp", + "name": "after", + "in": "query" + }, + { + "type": "boolean", + "description": "Follow log stream", + "name": "follow", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.ProvisionerJobLog" + } + } + } + } + } + }, "/templateversions/{id}/schema": { "get": { "security": [ @@ -939,6 +1032,179 @@ } } }, + "/templateversions/{templateversionid}/dry-run/{jobid}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get template version dry-run by job ID", + "operationId": "get-template-version-dry-run-by-job-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversionid", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "Job ID", + "name": "jobid", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.ProvisionerJob" + } + } + } + } + }, + "/templateversions/{templateversionid}/dry-run/{jobid}/cancel": { + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Cancel template version dry-run by job ID", + "operationId": "cancel-template-version-dry-run-by-job-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, + "/templateversions/{templateversionid}/dry-run/{jobid}/logs": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get template version dry-run logs by job ID", + "operationId": "get-template-version-dry-run-logs-by-job-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversionid", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "Job ID", + "name": "jobid", + "in": "path", + "required": true + }, + { + "type": "integer", + "description": "Before Unix timestamp", + "name": "before", + "in": "query" + }, + { + "type": "integer", + "description": "After Unix timestamp", + "name": "after", + "in": "query" + }, + { + "type": "boolean", + "description": "Follow log stream", + "name": "follow", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.ProvisionerJobLog" + } + } + } + } + } + }, + "/templateversions/{templateversionid}/dry-run/{jobid}/resources": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get template version dry-run resources by job ID", + "operationId": "get-template-version-dry-run-resources-by-job-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversionid", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "Job ID", + "name": "jobid", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceResource" + } + } + } + } + } + }, "/updatecheck": { "get": { "produces": ["application/json"], @@ -2163,6 +2429,20 @@ } } }, + "codersdk.CreateTemplateVersionDryRunRequest": { + "type": "object", + "properties": { + "parameter_values": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.CreateParameterRequest" + } + }, + "workspace_name": { + "type": "string" + } + } + }, "codersdk.CreateTestAuditLogRequest": { "type": "object", "properties": { diff --git a/coderd/templateversions.go b/coderd/templateversions.go index 594d86e9c8888..9a6dc0d817583 100644 --- a/coderd/templateversions.go +++ b/coderd/templateversions.go @@ -245,6 +245,16 @@ func (api *API) templateVersionParameters(rw http.ResponseWriter, r *http.Reques httpapi.Write(ctx, rw, http.StatusOK, values) } +// @Summary Create template version dry-run +// @ID create-template-version-dry-run +// @Security CoderSessionToken +// @Accept json +// @Produce json +// @Tags Templates +// @Param id path string true "Template version ID" format(uuid) +// @Param request body codersdk.CreateTemplateVersionDryRunRequest true "Dry-run request" +// @Success 201 {object} codersdk.ProvisionerJob +// @Router /templateversions/{id}/dry-run [post] func (api *API) postTemplateVersionDryRun(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() var ( @@ -340,6 +350,16 @@ func (api *API) postTemplateVersionDryRun(rw http.ResponseWriter, r *http.Reques httpapi.Write(ctx, rw, http.StatusCreated, convertProvisionerJob(provisionerJob)) } +// @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 templateversionid path string true "Template version ID" format(uuid) +// @Param jobid path string true "Job ID" format(uuid) +// @Success 200 {object} codersdk.ProvisionerJob +// @Router /templateversions/{templateversionid}/dry-run/{jobid} [get] func (api *API) templateVersionDryRun(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() job, ok := api.fetchTemplateVersionDryRunJob(rw, r) @@ -350,6 +370,15 @@ func (api *API) templateVersionDryRun(rw http.ResponseWriter, r *http.Request) { httpapi.Write(ctx, rw, http.StatusOK, convertProvisionerJob(job)) } +// @Summary Get template version dry-run resources by job ID +// @ID get-template-version-dry-run-resources-by-job-id +// @Security CoderSessionToken +// @Produce json +// @Tags Templates +// @Param templateversionid path string true "Template version ID" format(uuid) +// @Param jobid path string true "Job ID" format(uuid) +// @Success 200 {array} codersdk.WorkspaceResource +// @Router /templateversions/{templateversionid}/dry-run/{jobid}/resources [get] func (api *API) templateVersionDryRunResources(rw http.ResponseWriter, r *http.Request) { job, ok := api.fetchTemplateVersionDryRunJob(rw, r) if !ok { @@ -359,6 +388,18 @@ func (api *API) templateVersionDryRunResources(rw http.ResponseWriter, r *http.R api.provisionerJobResources(rw, r, job) } +// @Summary Get template version dry-run logs by job ID +// @ID get-template-version-dry-run-logs-by-job-id +// @Security CoderSessionToken +// @Produce json +// @Tags Templates +// @Param templateversionid path string true "Template version 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/{templateversionid}/dry-run/{jobid}/logs [get] func (api *API) templateVersionDryRunLogs(rw http.ResponseWriter, r *http.Request) { job, ok := api.fetchTemplateVersionDryRunJob(rw, r) if !ok { @@ -368,6 +409,14 @@ func (api *API) templateVersionDryRunLogs(rw http.ResponseWriter, r *http.Reques api.provisionerJobLogs(rw, r, job) } +// @Summary Cancel template version dry-run by job ID +// @ID cancel-template-version-dry-run-by-job-id +// @Security CoderSessionToken +// @Produce json +// @Tags Templates +// @Param id path string true "Template version ID" format(uuid) +// @Success 200 {object} codersdk.Response +// @Router /templateversions/{templateversionid}/dry-run/{jobid}/cancel [patch] func (api *API) patchTemplateVersionDryRunCancel(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() templateVersion := httpmw.TemplateVersionParam(r) @@ -1126,6 +1175,15 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht httpapi.Write(ctx, rw, http.StatusCreated, convertTemplateVersion(templateVersion, convertProvisionerJob(provisionerJob), user)) } +// @Summary Get template version resources by template version ID +// @ID get-template-version-resources-by-template-version-id +// @Security CoderSessionToken +// @Produce json +// @Tags Templates +// @Param id path string true "Template version ID" format(uuid) +// @Success 200 {array} codersdk.WorkspaceResource +// @Router /templateversions/{id}/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 @@ -1154,6 +1212,18 @@ func (api *API) templateVersionResources(rw http.ResponseWriter, r *http.Request api.provisionerJobResources(rw, r, job) } +// @Summary Get template version logs by template version ID +// @ID get-template-version-resources-by-template-version-id +// @Security CoderSessionToken +// @Produce json +// @Tags Templates +// @Param id path string true "Template version 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/{id}/resources [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. diff --git a/docs/api/schemas.md b/docs/api/schemas.md index ab8bfa6a5fb3a..c4f98b5cd5fa1 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -474,6 +474,30 @@ CreateParameterRequest is a structure used to create a new parameter value for a | `template_version_id` | string | true | | Template version ID is an in-progress or completed job to use as an initial version of the template. | | 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. | +## codersdk.CreateTemplateVersionDryRunRequest + +```json +{ + "parameter_values": [ + { + "copy_from_parameter": "000e07d6-021d-446c-be14-48a9c20bca0b", + "destination_scheme": "none", + "name": "string", + "source_scheme": "none", + "source_value": "string" + } + ], + "workspace_name": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ------------------ | --------------------------------------------------------------------------- | -------- | ------------ | ---------------------------------------------------------------------------------- | +| `parameter_values` | array of [codersdk.CreateParameterRequest](#codersdkcreateparameterrequest) | false | | Parameter values is a structure used to create a new parameter value for a scope.] | +| `workspace_name` | string | false | | | + ## codersdk.CreateTestAuditLogRequest ```json diff --git a/docs/api/templates.md b/docs/api/templates.md index b17668cda1b1a..013c126d476e8 100644 --- a/docs/api/templates.md +++ b/docs/api/templates.md @@ -883,6 +883,145 @@ curl -X PATCH http://coder-server:8080/api/v2/templateversions/{id}/cancel \ To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. +## Create template version dry-run + +### Code samples + +```shell +# Example request using curl +curl -X POST http://coder-server:8080/api/v2/templateversions/{id}/dry-run \ + -H 'Content-Type: application/json' \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`POST /templateversions/{id}/dry-run` + +> Body parameter + +```json +{ + "parameter_values": [ + { + "copy_from_parameter": "000e07d6-021d-446c-be14-48a9c20bca0b", + "destination_scheme": "none", + "name": "string", + "source_scheme": "none", + "source_value": "string" + } + ], + "workspace_name": "string" +} +``` + +### Parameters + +| Name | In | Type | Required | Description | +| ------ | ---- | ---------------------------------------------------------------------------------------------------- | -------- | ------------------- | +| `id` | path | string(uuid) | true | Template version ID | +| `body` | body | [codersdk.CreateTemplateVersionDryRunRequest](schemas.md#codersdkcreatetemplateversiondryrunrequest) | true | Dry-run request | + +### Example responses + +> 201 Response + +```json +{ + "canceled_at": "2019-08-24T14:15:22Z", + "completed_at": "2019-08-24T14:15:22Z", + "created_at": "2019-08-24T14:15:22Z", + "error": "string", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------------ | ----------- | ------------------------------------------------------------ | +| 201 | [Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) | Created | [codersdk.ProvisionerJob](schemas.md#codersdkprovisionerjob) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Get template version logs by template version ID + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/templateversions/{id}/resources \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /templateversions/{id}/resources` + +### Parameters + +| Name | In | Type | Required | Description | +| -------- | ----- | ------------ | -------- | --------------------- | +| `id` | path | string(uuid) | true | Template version ID | +| `before` | query | integer | false | Before Unix timestamp | +| `after` | query | integer | false | After Unix timestamp | +| `follow` | query | boolean | false | Follow log stream | + +### Example responses + +> 200 Response + +```json +[ + { + "created_at": "2019-08-24T14:15:22Z", + "id": 0, + "log_level": "trace", + "log_source": "string", + "output": "string", + "stage": "string" + } +] +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | --------------------------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | array of [codersdk.ProvisionerJobLog](schemas.md#codersdkprovisionerjoblog) | + +

Response Schema

+ +Status Code **200** + +| Name | Type | Required | Restrictions | Description | +| -------------- | ------- | -------- | ------------ | ----------- | +| `[array item]` | array | false | | | +| `» created_at` | string | false | | | +| `» id` | integer | false | | | +| `» log_level` | string | false | | | +| `» log_source` | string | false | | | +| `» output` | string | false | | | +| `» stage` | string | false | | | + +#### Enumerated Values + +| Property | Value | +| ----------- | ------- | +| `log_level` | `trace` | +| `log_level` | `debug` | +| `log_level` | `info` | +| `log_level` | `warn` | +| `log_level` | `error` | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + ## Get template version schema by ID ### Code samples @@ -950,3 +1089,353 @@ Status Code **200** | `» updated_at` | string | false | | | To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Get template version dry-run by job ID + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversionid}/dry-run/{jobid} \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /templateversions/{templateversionid}/dry-run/{jobid}` + +### Parameters + +| Name | In | Type | Required | Description | +| ------------------- | ---- | ------------ | -------- | ------------------- | +| `templateversionid` | path | string(uuid) | true | Template version ID | +| `jobid` | path | string(uuid) | true | Job ID | + +### Example responses + +> 200 Response + +```json +{ + "canceled_at": "2019-08-24T14:15:22Z", + "completed_at": "2019-08-24T14:15:22Z", + "created_at": "2019-08-24T14:15:22Z", + "error": "string", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ------------------------------------------------------------ | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.ProvisionerJob](schemas.md#codersdkprovisionerjob) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Cancel template version dry-run by job ID + +### Code samples + +```shell +# Example request using curl +curl -X PATCH http://coder-server:8080/api/v2/templateversions/{templateversionid}/dry-run/{jobid}/cancel \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`PATCH /templateversions/{templateversionid}/dry-run/{jobid}/cancel` + +### Parameters + +| Name | In | Type | Required | Description | +| ---- | ---- | ------------ | -------- | ------------------- | +| `id` | path | string(uuid) | true | Template version ID | + +### Example responses + +> 200 Response + +```json +{ + "detail": "string", + "message": "string", + "validations": [ + { + "detail": "string", + "field": "string" + } + ] +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ------------------------------------------------ | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.Response](schemas.md#codersdkresponse) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Get template version dry-run logs by job ID + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversionid}/dry-run/{jobid}/logs \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /templateversions/{templateversionid}/dry-run/{jobid}/logs` + +### Parameters + +| Name | In | Type | Required | Description | +| ------------------- | ----- | ------------ | -------- | --------------------- | +| `templateversionid` | path | string(uuid) | true | Template version 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 | + +### Example responses + +> 200 Response + +```json +[ + { + "created_at": "2019-08-24T14:15:22Z", + "id": 0, + "log_level": "trace", + "log_source": "string", + "output": "string", + "stage": "string" + } +] +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | --------------------------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | array of [codersdk.ProvisionerJobLog](schemas.md#codersdkprovisionerjoblog) | + +

Response Schema

+ +Status Code **200** + +| Name | Type | Required | Restrictions | Description | +| -------------- | ------- | -------- | ------------ | ----------- | +| `[array item]` | array | false | | | +| `» created_at` | string | false | | | +| `» id` | integer | false | | | +| `» log_level` | string | false | | | +| `» log_source` | string | false | | | +| `» output` | string | false | | | +| `» stage` | string | false | | | + +#### Enumerated Values + +| Property | Value | +| ----------- | ------- | +| `log_level` | `trace` | +| `log_level` | `debug` | +| `log_level` | `info` | +| `log_level` | `warn` | +| `log_level` | `error` | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Get template version dry-run resources by job ID + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversionid}/dry-run/{jobid}/resources \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /templateversions/{templateversionid}/dry-run/{jobid}/resources` + +### Parameters + +| Name | In | Type | Required | Description | +| ------------------- | ---- | ------------ | -------- | ------------------- | +| `templateversionid` | path | string(uuid) | true | Template version ID | +| `jobid` | path | string(uuid) | true | Job ID | + +### Example responses + +> 200 Response + +```json +[ + { + "agents": [ + { + "apps": [ + { + "command": "string", + "display_name": "string", + "external": true, + "health": "string", + "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" + } + ], + "created_at": "2019-08-24T14:15:22Z", + "daily_cost": 0, + "hide": true, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f", + "metadata": [ + { + "key": "string", + "sensitive": true, + "value": "string" + } + ], + "name": "string", + "type": "string", + "workspace_transition": "start" + } +] +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | --------------------------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | array of [codersdk.WorkspaceResource](schemas.md#codersdkworkspaceresource) | + +

Response Schema

+ +Status Code **200** + +| Name | Type | Required | Restrictions | Description | +| ------------------------------- | ---------------------- | -------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `[array item]` | array | false | | | +| `» agents` | array | false | | | +| `»» apps` | array | false | | | +| `»»» command` | string | false | | | +| `»»» display_name` | string | false | | DisplayName is a friendly name for the app. | +| `»»» external` | boolean | false | | External specifies whether the URL should be opened externally on
the client or not. | +| `»»» health` | string | false | | | +| `»»» healthcheck` | `codersdk.Healthcheck` | false | | | +| `»»»» interval` | integer | false | | Interval specifies the seconds between each health check. | +| `»»»» threshold` | integer | false | | Threshold specifies the number of consecutive failed health checks before returning "unhealthy". | +| `»»»» url` | string | false | | URL specifies the endpoint to check for the app health. | +| `»»» icon` | string | false | | Icon is a relative path or external URL that specifies
an icon to be displayed in the dashboard. | +| `»»» id` | string | false | | | +| `»»» sharing_level` | string | false | | | +| `»»» slug` | string | false | | Slug is a unique identifier within the agent. | +| `»»» subdomain` | boolean | false | | Subdomain denotes whether the app should be accessed via a path on the
`coder server` or via a hostname-based dev URL. If this is set to true
and there is no app wildcard configured on the server, the app will not
be accessible in the UI. | +| `»»» url` | string | false | | URL is the address being proxied to inside the workspace.
If external is specified, this will be opened on the client. | +| `»» architecture` | string | false | | | +| `»» connection_timeout_seconds` | integer | false | | | +| `»» created_at` | string | false | | | +| `»» directory` | string | false | | | +| `»» disconnected_at` | string | false | | | +| `»» environment_variables` | object | false | | | +| `»»» [any property]` | string | false | | | +| `»» first_connected_at` | string | false | | | +| `»» id` | string | false | | | +| `»» instance_id` | string | false | | | +| `»» last_connected_at` | string | false | | | +| `»» latency` | object | false | | DERPLatency is mapped by region name (e.g. "New York City", "Seattle"). | +| `»»» [any property]` | `codersdk.DERPRegion` | false | | | +| `»»»» latency_ms` | number | false | | | +| `»»»» preferred` | boolean | false | | | +| `»» name` | string | false | | | +| `»» operating_system` | string | false | | | +| `»» resource_id` | string | false | | | +| `»» startup_script` | string | false | | | +| `»» status` | string | false | | | +| `»» troubleshooting_url` | string | false | | | +| `»» updated_at` | string | false | | | +| `»» version` | string | false | | | +| `» created_at` | string | false | | | +| `» daily_cost` | integer | false | | | +| `» hide` | boolean | false | | | +| `» icon` | string | false | | | +| `» id` | string | false | | | +| `» job_id` | string | false | | | +| `» metadata` | array | false | | | +| `»» key` | string | false | | | +| `»» sensitive` | boolean | false | | | +| `»» value` | string | false | | | +| `» name` | string | false | | | +| `» type` | string | false | | | +| `» workspace_transition` | string | false | | | + +#### Enumerated Values + +| Property | Value | +| ---------------------- | --------------- | +| `sharing_level` | `owner` | +| `sharing_level` | `authenticated` | +| `sharing_level` | `public` | +| `status` | `connecting` | +| `status` | `connected` | +| `status` | `disconnected` | +| `status` | `timeout` | +| `workspace_transition` | `start` | +| `workspace_transition` | `stop` | +| `workspace_transition` | `delete` | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. From 15de3b6e8ea6c4f15ff747792689ddab77e9bdd4 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Tue, 3 Jan 2023 17:09:12 +0100 Subject: [PATCH 14/36] wip --- coderd/apidoc/docs.go | 108 +++++++++++++++++++++++++++++++++++++ coderd/apidoc/swagger.json | 93 ++++++++++++++++++++++++++++++++ coderd/organizations.go | 16 ++++++ codersdk/organizations.go | 6 +-- docs/api/organizations.md | 92 +++++++++++++++++++++++++++++++ docs/api/schemas.md | 34 ++++++++++++ docs/manifest.json | 4 ++ 7 files changed, 350 insertions(+), 3 deletions(-) create mode 100644 docs/api/organizations.md diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index a03103999f70d..173a04b9151a0 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -378,6 +378,77 @@ const docTemplate = `{ } } }, + "/organizations": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Organizations" + ], + "summary": "Create organization", + "operationId": "create-organization", + "parameters": [ + { + "description": "Create organization request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateOrganizationRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.Organization" + } + } + } + } + }, + "/organizations/{id}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Organizations" + ], + "summary": "Get organization by ID", + "operationId": "get-organization-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Organization" + } + } + } + } + }, "/organizations/{organization-id}/templates/": { "post": { "security": [ @@ -2660,6 +2731,17 @@ const docTemplate = `{ } } }, + "codersdk.CreateOrganizationRequest": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string" + } + } + }, "codersdk.CreateParameterRequest": { "description": "CreateParameterRequest is a structure used to create a new parameter value for a scope.", "type": "object", @@ -3335,6 +3417,32 @@ const docTemplate = `{ } } }, + "codersdk.Organization": { + "type": "object", + "required": [ + "created_at", + "id", + "name", + "updated_at" + ], + "properties": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "updated_at": { + "type": "string", + "format": "date-time" + } + } + }, "codersdk.Parameter": { "description": "Parameter represents a set value for the scope.", "type": "object", diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index fb79b44971a4c..ebb867336dc27 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -324,6 +324,69 @@ } } }, + "/organizations": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Organizations"], + "summary": "Create organization", + "operationId": "create-organization", + "parameters": [ + { + "description": "Create organization request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateOrganizationRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.Organization" + } + } + } + } + }, + "/organizations/{id}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Organizations"], + "summary": "Get organization by ID", + "operationId": "get-organization-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Organization" + } + } + } + } + }, "/organizations/{organization-id}/templates/": { "post": { "security": [ @@ -2358,6 +2421,15 @@ } } }, + "codersdk.CreateOrganizationRequest": { + "type": "object", + "required": ["name"], + "properties": { + "name": { + "type": "string" + } + } + }, "codersdk.CreateParameterRequest": { "description": "CreateParameterRequest is a structure used to create a new parameter value for a scope.", "type": "object", @@ -3008,6 +3080,27 @@ } } }, + "codersdk.Organization": { + "type": "object", + "required": ["created_at", "id", "name", "updated_at"], + "properties": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "updated_at": { + "type": "string", + "format": "date-time" + } + } + }, "codersdk.Parameter": { "description": "Parameter represents a set value for the scope.", "type": "object", diff --git a/coderd/organizations.go b/coderd/organizations.go index 27da001482f2d..ddbd38ac3d785 100644 --- a/coderd/organizations.go +++ b/coderd/organizations.go @@ -16,6 +16,14 @@ import ( "github.com/coder/coder/codersdk" ) +// @Summary Get organization by ID +// @ID get-organization-by-id +// @Security CoderSessionToken +// @Produce json +// @Tags Organizations +// @Param id path string true "Organization ID" format(uuid) +// @Success 200 {object} codersdk.Organization +// @Router /organizations/{id} [get] func (api *API) organization(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() organization := httpmw.OrganizationParam(r) @@ -29,6 +37,14 @@ func (api *API) organization(rw http.ResponseWriter, r *http.Request) { httpapi.Write(ctx, rw, http.StatusOK, convertOrganization(organization)) } +// @Summary Create organization +// @ID create-organization +// @Security CoderSessionToken +// @Produce json +// @Tags Organizations +// @Param request body codersdk.CreateOrganizationRequest true "Create organization request" +// @Success 201 {object} codersdk.Organization +// @Router /organizations [post] func (api *API) postOrganizations(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() apiKey := httpmw.APIKey(r) diff --git a/codersdk/organizations.go b/codersdk/organizations.go index 2c15e78db1c69..39b50da013ec5 100644 --- a/codersdk/organizations.go +++ b/codersdk/organizations.go @@ -26,10 +26,10 @@ const ( // Organization is the JSON representation of a Coder organization. type Organization struct { - ID uuid.UUID `json:"id" validate:"required"` + ID uuid.UUID `json:"id" validate:"required" format:"uuid"` Name string `json:"name" validate:"required"` - CreatedAt time.Time `json:"created_at" validate:"required"` - UpdatedAt time.Time `json:"updated_at" validate:"required"` + CreatedAt time.Time `json:"created_at" validate:"required" format:"date-time"` + UpdatedAt time.Time `json:"updated_at" validate:"required" format:"date-time"` } // CreateTemplateVersionRequest enables callers to create a new Template Version. diff --git a/docs/api/organizations.md b/docs/api/organizations.md new file mode 100644 index 0000000000000..0fd429e8ceb03 --- /dev/null +++ b/docs/api/organizations.md @@ -0,0 +1,92 @@ +# Organizations + +> This page is incomplete, stay tuned. + +## Create organization + +### Code samples + +```shell +# Example request using curl +curl -X POST http://coder-server:8080/api/v2/organizations \ + -H 'Content-Type: application/json' \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`POST /organizations` + +> Body parameter + +```json +{ + "name": "string" +} +``` + +### Parameters + +| Name | In | Type | Required | Description | +| ------ | ---- | ---------------------------------------------------------------------------------- | -------- | --------------------------- | +| `body` | body | [codersdk.CreateOrganizationRequest](schemas.md#codersdkcreateorganizationrequest) | true | Create organization request | + +### Example responses + +> 201 Response + +```json +{ + "created_at": "2019-08-24T14:15:22Z", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "string", + "updated_at": "2019-08-24T14:15:22Z" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------------ | ----------- | -------------------------------------------------------- | +| 201 | [Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) | Created | [codersdk.Organization](schemas.md#codersdkorganization) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Get organization by ID + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/organizations/{id} \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /organizations/{id}` + +### Parameters + +| Name | In | Type | Required | Description | +| ---- | ---- | ------------ | -------- | --------------- | +| `id` | path | string(uuid) | true | Organization ID | + +### Example responses + +> 200 Response + +```json +{ + "created_at": "2019-08-24T14:15:22Z", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "string", + "updated_at": "2019-08-24T14:15:22Z" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | -------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.Organization](schemas.md#codersdkorganization) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. diff --git a/docs/api/schemas.md b/docs/api/schemas.md index c4f98b5cd5fa1..90ed168c1f7e3 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -403,6 +403,20 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in | `external_url` | string | false | | External URL references the current Coder version. For production builds, this will link directly to a release. For development builds, this will link to a commit. | | `version` | string | false | | Version returns the semantic version of the build. | +## codersdk.CreateOrganizationRequest + +```json +{ + "name": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ------ | ------ | -------- | ------------ | ----------- | +| `name` | string | true | | | + ## codersdk.CreateParameterRequest ```json @@ -2273,6 +2287,26 @@ CreateParameterRequest is a structure used to create a new parameter value for a | `issuer_url` | [codersdk.DeploymentConfigField-string](#codersdkdeploymentconfigfield-string) | false | | | | `scopes` | [codersdk.DeploymentConfigField-array_string](#codersdkdeploymentconfigfield-array_string) | false | | | +## codersdk.Organization + +```json +{ + "created_at": "2019-08-24T14:15:22Z", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "string", + "updated_at": "2019-08-24T14:15:22Z" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ------------ | ------ | -------- | ------------ | ----------- | +| `created_at` | string | true | | | +| `id` | string | true | | | +| `name` | string | true | | | +| `updated_at` | string | true | | | + ## codersdk.Parameter ```json diff --git a/docs/manifest.json b/docs/manifest.json index 079735f2800bb..0d5a7ad0c4144 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -349,6 +349,10 @@ "title": "Files", "path": "./api/files.md" }, + { + "title": "Organizations", + "path": "./api/organizations.md" + }, { "title": "Templates", "path": "./api/templates.md" From eb4ba489511026f1502a023299dc0ea1563bffa2 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Tue, 3 Jan 2023 19:27:02 +0100 Subject: [PATCH 15/36] Merge --- coderd/apidoc/docs.go | 48 +------------------- coderd/apidoc/swagger.json | 44 +----------------- docs/api/builds.md | 92 +++++++++++++++++++------------------- docs/api/files.md | 17 ------- docs/api/parameters.md | 30 ------------- docs/api/schemas.md | 27 ----------- docs/manifest.json | 3 -- 7 files changed, 50 insertions(+), 211 deletions(-) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 86102cff2563b..1e00cda9d61ac 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -310,11 +310,7 @@ const docTemplate = `{ "CoderSessionToken": [] } ], -<<<<<<< HEAD - "description": "Notice: Swagger 2.0 doesn't support file upload with a ` + "`" + `content-type` + "`" + ` different than ` + "`" + `application/x-www-form-urlencoded` + "`" + `.", -======= "description": "Swagger notice: Swagger 2.0 doesn't support file upload with a ` + "`" + `content-type` + "`" + ` different than ` + "`" + `application/x-www-form-urlencoded` + "`" + `.", ->>>>>>> main "consumes": [ "application/x-tar" ], @@ -1852,7 +1848,6 @@ const docTemplate = `{ } } }, -<<<<<<< HEAD "codersdk.AWSInstanceIdentityToken": { "type": "object", "required": [ @@ -1920,8 +1915,6 @@ const docTemplate = `{ } } }, -======= ->>>>>>> main "codersdk.AuditDiff": { "type": "object", "additionalProperties": { @@ -2217,7 +2210,6 @@ const docTemplate = `{ } } }, -<<<<<<< HEAD "codersdk.CreateWorkspaceBuildRequest": { "type": "object", "required": [ @@ -2258,8 +2250,6 @@ const docTemplate = `{ } } }, -======= ->>>>>>> main "codersdk.DERP": { "type": "object", "properties": { @@ -2666,7 +2656,6 @@ const docTemplate = `{ } } }, -<<<<<<< HEAD "codersdk.GoogleInstanceIdentityToken": { "type": "object", "required": [ @@ -2678,8 +2667,6 @@ const docTemplate = `{ } } }, -======= ->>>>>>> main "codersdk.Healthcheck": { "type": "object", "properties": { @@ -2762,25 +2749,6 @@ const docTemplate = `{ "type": "object", "properties": { "created_at": { -<<<<<<< HEAD - "type": "string" - }, - "destination_scheme": { - "type": "string", - "enum": [ - "none", - "environment_variable", - "provisioner_variable" - ] - }, - "id": { - "type": "string", - "format": "uuid" - }, - "name": { - "type": "string" - }, -======= "type": "string", "format": "date-time" }, @@ -2799,7 +2767,6 @@ const docTemplate = `{ "name": { "type": "string" }, ->>>>>>> main "scope": { "type": "string", "enum": [ @@ -2820,8 +2787,8 @@ const docTemplate = `{ ] }, "updated_at": { -<<<<<<< HEAD - "type": "string" + "type": "string", + "format": "date-time" } } }, @@ -2842,10 +2809,6 @@ const docTemplate = `{ "additionalProperties": { "type": "string" } -======= - "type": "string", - "format": "date-time" ->>>>>>> main } } }, @@ -3211,12 +3174,8 @@ const docTemplate = `{ "type": "object", "properties": { "hash": { -<<<<<<< HEAD - "type": "string" -======= "type": "string", "format": "uuid" ->>>>>>> main } } }, @@ -3712,7 +3671,6 @@ const docTemplate = `{ }, "netip.Addr": { "type": "object" -<<<<<<< HEAD }, "tailcfg.DERPMap": { "type": "object", @@ -3814,8 +3772,6 @@ const docTemplate = `{ "type": "string" } } -======= ->>>>>>> main } }, "securityDefinitions": { diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index d9523fa16c757..304cac3b05ee9 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -264,11 +264,7 @@ "CoderSessionToken": [] } ], -<<<<<<< HEAD - "description": "Notice: Swagger 2.0 doesn't support file upload with a `content-type` different than `application/x-www-form-urlencoded`.", -======= "description": "Swagger notice: Swagger 2.0 doesn't support file upload with a `content-type` different than `application/x-www-form-urlencoded`.", ->>>>>>> main "consumes": ["application/x-tar"], "produces": ["application/json"], "tags": ["Files"], @@ -1619,7 +1615,6 @@ } } }, -<<<<<<< HEAD "codersdk.AWSInstanceIdentityToken": { "type": "object", "required": ["document", "signature"], @@ -1684,8 +1679,6 @@ } } }, -======= ->>>>>>> main "codersdk.AuditDiff": { "type": "object", "additionalProperties": { @@ -1957,7 +1950,6 @@ } } }, -<<<<<<< HEAD "codersdk.CreateWorkspaceBuildRequest": { "type": "object", "required": ["transition"], @@ -1991,8 +1983,6 @@ } } }, -======= ->>>>>>> main "codersdk.DERP": { "type": "object", "properties": { @@ -2399,7 +2389,6 @@ } } }, -<<<<<<< HEAD "codersdk.GoogleInstanceIdentityToken": { "type": "object", "required": ["json_web_token"], @@ -2409,8 +2398,6 @@ } } }, -======= ->>>>>>> main "codersdk.Healthcheck": { "type": "object", "properties": { @@ -2493,21 +2480,6 @@ "type": "object", "properties": { "created_at": { -<<<<<<< HEAD - "type": "string" - }, - "destination_scheme": { - "type": "string", - "enum": ["none", "environment_variable", "provisioner_variable"] - }, - "id": { - "type": "string", - "format": "uuid" - }, - "name": { - "type": "string" - }, -======= "type": "string", "format": "date-time" }, @@ -2522,7 +2494,6 @@ "name": { "type": "string" }, ->>>>>>> main "scope": { "type": "string", "enum": ["template", "workspace", "import_job"] @@ -2536,8 +2507,8 @@ "enum": ["none", "data"] }, "updated_at": { -<<<<<<< HEAD - "type": "string" + "type": "string", + "format": "date-time" } } }, @@ -2558,10 +2529,6 @@ "additionalProperties": { "type": "string" } -======= - "type": "string", - "format": "date-time" ->>>>>>> main } } }, @@ -2919,12 +2886,8 @@ "type": "object", "properties": { "hash": { -<<<<<<< HEAD - "type": "string" -======= "type": "string", "format": "uuid" ->>>>>>> main } } }, @@ -3391,7 +3354,6 @@ }, "netip.Addr": { "type": "object" -<<<<<<< HEAD }, "tailcfg.DERPMap": { "type": "object", @@ -3493,8 +3455,6 @@ "type": "string" } } -======= ->>>>>>> main } }, "securityDefinitions": { diff --git a/docs/api/builds.md b/docs/api/builds.md index 2eea39745c4ea..a58f9c0b61b3b 100644 --- a/docs/api/builds.md +++ b/docs/api/builds.md @@ -237,15 +237,15 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/log Status Code **200** -| Name | Type | Required | Restrictions | Description | -| -------------- | ------- | -------- | ------------ | ----------- | -| `[array item]` | array | false | | | -| `» created_at` | string | false | | | -| `» id` | integer | false | | | -| `» log_level` | string | false | | | -| `» log_source` | string | false | | | -| `» output` | string | false | | | -| `» stage` | string | false | | | +| Name | Type | Required | Restrictions | Description | +| -------------- | ----------------- | -------- | ------------ | ----------- | +| `[array item]` | array | false | | | +| `» created_at` | string(date-time) | false | | | +| `» id` | integer | false | | | +| `» log_level` | string | false | | | +| `» log_source` | string | false | | | +| `» output` | string | false | | | +| `» stage` | string | false | | | #### Enumerated Values @@ -383,40 +383,40 @@ Status Code **200** | `»»»» threshold` | integer | false | | Threshold specifies the number of consecutive failed health checks before returning "unhealthy". | | `»»»» url` | string | false | | URL specifies the endpoint to check for the app health. | | `»»» icon` | string | false | | Icon is a relative path or external URL that specifies
an icon to be displayed in the dashboard. | -| `»»» id` | string | false | | | +| `»»» id` | string(uuid) | false | | | | `»»» sharing_level` | string | false | | | | `»»» slug` | string | false | | Slug is a unique identifier within the agent. | | `»»» subdomain` | boolean | false | | Subdomain denotes whether the app should be accessed via a path on the
`coder server` or via a hostname-based dev URL. If this is set to true
and there is no app wildcard configured on the server, the app will not
be accessible in the UI. | | `»»» url` | string | false | | URL is the address being proxied to inside the workspace.
If external is specified, this will be opened on the client. | | `»» architecture` | string | false | | | | `»» connection_timeout_seconds` | integer | false | | | -| `»» created_at` | string | false | | | +| `»» created_at` | string(date-time) | false | | | | `»» directory` | string | false | | | -| `»» disconnected_at` | string | false | | | +| `»» disconnected_at` | string(date-time) | false | | | | `»» environment_variables` | object | false | | | | `»»» [any property]` | string | false | | | -| `»» first_connected_at` | string | false | | | -| `»» id` | string | false | | | +| `»» first_connected_at` | string(date-time) | false | | | +| `»» id` | string(uuid) | false | | | | `»» instance_id` | string | false | | | -| `»» last_connected_at` | string | false | | | +| `»» last_connected_at` | string(date-time) | false | | | | `»» latency` | object | false | | DERPLatency is mapped by region name (e.g. "New York City", "Seattle"). | | `»»» [any property]` | `codersdk.DERPRegion` | false | | | | `»»»» latency_ms` | number | false | | | | `»»»» preferred` | boolean | false | | | | `»» name` | string | false | | | | `»» operating_system` | string | false | | | -| `»» resource_id` | string | false | | | +| `»» resource_id` | string(uuid) | false | | | | `»» startup_script` | string | false | | | | `»» status` | string | false | | | | `»» troubleshooting_url` | string | false | | | -| `»» updated_at` | string | false | | | +| `»» updated_at` | string(date-time) | false | | | | `»» version` | string | false | | | -| `» created_at` | string | false | | | +| `» created_at` | string(date-time) | false | | | | `» daily_cost` | integer | false | | | | `» hide` | boolean | false | | | | `» icon` | string | false | | | -| `» id` | string | false | | | -| `» job_id` | string | false | | | +| `» id` | string(uuid) | false | | | +| `» job_id` | string(uuid) | false | | | | `» metadata` | array | false | | | | `»» key` | string | false | | | | `»» sensitive` | boolean | false | | | @@ -738,24 +738,24 @@ Status Code **200** | -------------------------------- | ------------------------- | -------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `[array item]` | array | false | | | | `» build_number` | integer | false | | | -| `» created_at` | string | false | | | +| `» created_at` | string(date-time) | false | | | | `» daily_cost` | integer | false | | | -| `» deadline` | string | false | | | -| `» id` | string | false | | | -| `» initiator_id` | string | false | | | +| `» deadline` | string(date-time) | false | | | +| `» id` | string(uuid) | false | | | +| `» initiator_id` | string(uuid) | false | | | | `» initiator_name` | string | false | | | | `» job` | `codersdk.ProvisionerJob` | false | | | -| `»» canceled_at` | string | false | | | -| `»» completed_at` | string | false | | | -| `»» created_at` | string | false | | | +| `»» canceled_at` | string(date-time) | false | | | +| `»» completed_at` | string(date-time) | false | | | +| `»» created_at` | string(date-time) | false | | | | `»» error` | string | false | | | -| `»» file_id` | string | false | | | -| `»» id` | string | false | | | -| `»» started_at` | string | false | | | +| `»» file_id` | string(uuid) | false | | | +| `»» id` | string(uuid) | false | | | +| `»» started_at` | string(date-time) | false | | | | `»» status` | string | false | | | | `»» tags` | object | false | | | | `»»» [any property]` | string | false | | | -| `»» worker_id` | string | false | | | +| `»» worker_id` | string(uuid) | false | | | | `» reason` | string | false | | | | `» resources` | array | false | | | | `»» agents` | array | false | | | @@ -769,40 +769,40 @@ Status Code **200** | `»»»»» threshold` | integer | false | | Threshold specifies the number of consecutive failed health checks before returning "unhealthy". | | `»»»»» url` | string | false | | URL specifies the endpoint to check for the app health. | | `»»»» icon` | string | false | | Icon is a relative path or external URL that specifies
an icon to be displayed in the dashboard. | -| `»»»» id` | string | false | | | +| `»»»» id` | string(uuid) | false | | | | `»»»» sharing_level` | string | false | | | | `»»»» slug` | string | false | | Slug is a unique identifier within the agent. | | `»»»» subdomain` | boolean | false | | Subdomain denotes whether the app should be accessed via a path on the
`coder server` or via a hostname-based dev URL. If this is set to true
and there is no app wildcard configured on the server, the app will not
be accessible in the UI. | | `»»»» url` | string | false | | URL is the address being proxied to inside the workspace.
If external is specified, this will be opened on the client. | | `»»» architecture` | string | false | | | | `»»» connection_timeout_seconds` | integer | false | | | -| `»»» created_at` | string | false | | | +| `»»» created_at` | string(date-time) | false | | | | `»»» directory` | string | false | | | -| `»»» disconnected_at` | string | false | | | +| `»»» disconnected_at` | string(date-time) | false | | | | `»»» environment_variables` | object | false | | | | `»»»» [any property]` | string | false | | | -| `»»» first_connected_at` | string | false | | | -| `»»» id` | string | false | | | +| `»»» first_connected_at` | string(date-time) | false | | | +| `»»» id` | string(uuid) | false | | | | `»»» instance_id` | string | false | | | -| `»»» last_connected_at` | string | false | | | +| `»»» last_connected_at` | string(date-time) | false | | | | `»»» latency` | object | false | | DERPLatency is mapped by region name (e.g. "New York City", "Seattle"). | | `»»»» [any property]` | `codersdk.DERPRegion` | false | | | | `»»»»» latency_ms` | number | false | | | | `»»»»» preferred` | boolean | false | | | | `»»» name` | string | false | | | | `»»» operating_system` | string | false | | | -| `»»» resource_id` | string | false | | | +| `»»» resource_id` | string(uuid) | false | | | | `»»» startup_script` | string | false | | | | `»»» status` | string | false | | | | `»»» troubleshooting_url` | string | false | | | -| `»»» updated_at` | string | false | | | +| `»»» updated_at` | string(date-time) | false | | | | `»»» version` | string | false | | | -| `»» created_at` | string | false | | | +| `»» created_at` | string(date-time) | false | | | | `»» daily_cost` | integer | false | | | | `»» hide` | boolean | false | | | | `»» icon` | string | false | | | -| `»» id` | string | false | | | -| `»» job_id` | string | false | | | +| `»» id` | string(uuid) | false | | | +| `»» job_id` | string(uuid) | false | | | | `»» metadata` | array | false | | | | `»»» key` | string | false | | | | `»»» sensitive` | boolean | false | | | @@ -811,13 +811,13 @@ Status Code **200** | `»» type` | string | false | | | | `»» workspace_transition` | string | false | | | | `» status` | string | false | | | -| `» template_version_id` | string | false | | | +| `» template_version_id` | string(uuid) | false | | | | `» template_version_name` | string | false | | | | `» transition` | string | false | | | -| `» updated_at` | string | false | | | -| `» workspace_id` | string | false | | | +| `» updated_at` | string(date-time) | false | | | +| `» workspace_id` | string(uuid) | false | | | | `» workspace_name` | string | false | | | -| `» workspace_owner_id` | string | false | | | +| `» workspace_owner_id` | string(uuid) | false | | | | `» workspace_owner_name` | string | false | | | #### Enumerated Values diff --git a/docs/api/files.md b/docs/api/files.md index 8f576cff1ae45..c72493caabc71 100644 --- a/docs/api/files.md +++ b/docs/api/files.md @@ -16,11 +16,6 @@ curl -X POST http://coder-server:8080/api/v2/files \ `POST /files` -<<<<<<< HEAD -Notice: Swagger 2.0 doesn't support file upload with a `content-type` different than `application/x-www-form-urlencoded`. - -======= ->>>>>>> main > Body parameter ```yaml @@ -29,19 +24,11 @@ file: string ### Parameters -<<<<<<< HEAD -| Name | In | Type | Required | Description | -| -------------- | ------ | -------------- | -------- | ---------------------------------------- | -| `Content-Type` | header | string | true | Content-Type must be `application/x-tar` | -| `body` | body | object | true | | -| `» file` | body | string(binary) | true | File to be uploaded | -======= | Name | In | Type | Required | Description | | -------------- | ------ | ------ | -------- | ---------------------------------------- | | `Content-Type` | header | string | true | Content-Type must be `application/x-tar` | | `body` | body | object | true | | | `» file` | body | binary | true | File to be uploaded | ->>>>>>> main ### Example responses @@ -49,11 +36,7 @@ file: string ```json { -<<<<<<< HEAD - "hash": "string" -======= "hash": "19686d84-b10d-4f90-b18e-84fd3fa038fd" ->>>>>>> main } ``` diff --git a/docs/api/parameters.md b/docs/api/parameters.md index 809f4a575a00a..1612ac333a3df 100644 --- a/docs/api/parameters.md +++ b/docs/api/parameters.md @@ -37,22 +37,14 @@ curl -X GET http://coder-server:8080/api/v2/parameters/{scope}/{id} \ ```json [ { -<<<<<<< HEAD - "created_at": "string", -======= "created_at": "2019-08-24T14:15:22Z", ->>>>>>> main "destination_scheme": "none", "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "name": "string", "scope": "template", "scope_id": "5d3fe357-12dd-4f62-b004-6d1fb3b8454f", "source_scheme": "none", -<<<<<<< HEAD - "updated_at": "string" -======= "updated_at": "2019-08-24T14:15:22Z" ->>>>>>> main } ] ``` @@ -67,19 +59,6 @@ curl -X GET http://coder-server:8080/api/v2/parameters/{scope}/{id} \ Status Code **200** -<<<<<<< HEAD -| Name | Type | Required | Restrictions | Description | -| ---------------------- | ------ | -------- | ------------ | ------------------------------------------------- | -| `[array item]` | array | false | | [Parameter represents a set value for the scope.] | -| `» created_at` | string | false | | | -| `» destination_scheme` | string | false | | | -| `» id` | string | false | | | -| `» name` | string | false | | | -| `» scope` | string | false | | | -| `» scope_id` | string | false | | | -| `» source_scheme` | string | false | | | -| `» updated_at` | string | false | | | -======= | Name | Type | Required | Restrictions | Description | | ---------------------- | ----------------- | -------- | ------------ | ------------------------------------------------- | | `[array item]` | array | false | | [Parameter represents a set value for the scope.] | @@ -91,7 +70,6 @@ Status Code **200** | `» scope_id` | string(uuid) | false | | | | `» source_scheme` | string | false | | | | `» updated_at` | string(date-time) | false | | | ->>>>>>> main #### Enumerated Values @@ -156,22 +134,14 @@ curl -X POST http://coder-server:8080/api/v2/parameters/{scope}/{id} \ ```json { -<<<<<<< HEAD - "created_at": "string", -======= "created_at": "2019-08-24T14:15:22Z", ->>>>>>> main "destination_scheme": "none", "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "name": "string", "scope": "template", "scope_id": "5d3fe357-12dd-4f62-b004-6d1fb3b8454f", "source_scheme": "none", -<<<<<<< HEAD - "updated_at": "string" -======= "updated_at": "2019-08-24T14:15:22Z" ->>>>>>> main } ``` diff --git a/docs/api/schemas.md b/docs/api/schemas.md index 54eb113339e6b..79cab87aef2c4 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -16,7 +16,6 @@ | ------------ | ------ | -------- | ------------ | ----------- | | `csp-report` | object | false | | | -<<<<<<< HEAD ## codersdk.AWSInstanceIdentityToken ```json @@ -91,8 +90,6 @@ | ----------------- | ------- | -------- | ------------ | ------------------------------------------------------------------------------ | | `report_interval` | integer | false | | Report interval is the duration after which the agent should send stats again. | -======= ->>>>>>> main ## codersdk.AuditDiff ```json @@ -516,7 +513,6 @@ CreateParameterRequest is a structure used to create a new parameter value for a | `resource_type` | `api_key` | | `resource_type` | `group` | -<<<<<<< HEAD ## codersdk.CreateWorkspaceBuildRequest ```json @@ -558,8 +554,6 @@ CreateParameterRequest is a structure used to create a new parameter value for a | `transition` | `stop` | | `transition` | `delete` | -======= ->>>>>>> main ## codersdk.DERP ```json @@ -1923,7 +1917,6 @@ CreateParameterRequest is a structure used to create a new parameter value for a | `type` | string | false | | | | `validate_url` | string | false | | | -<<<<<<< HEAD ## codersdk.GoogleInstanceIdentityToken ```json @@ -1938,8 +1931,6 @@ CreateParameterRequest is a structure used to create a new parameter value for a | ---------------- | ------ | -------- | ------------ | ----------- | | `json_web_token` | string | true | | | -======= ->>>>>>> main ## codersdk.Healthcheck ```json @@ -2246,22 +2237,14 @@ CreateParameterRequest is a structure used to create a new parameter value for a ```json { -<<<<<<< HEAD - "created_at": "string", -======= "created_at": "2019-08-24T14:15:22Z", ->>>>>>> main "destination_scheme": "none", "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "name": "string", "scope": "template", "scope_id": "5d3fe357-12dd-4f62-b004-6d1fb3b8454f", "source_scheme": "none", -<<<<<<< HEAD - "updated_at": "string" -======= "updated_at": "2019-08-24T14:15:22Z" ->>>>>>> main } ``` @@ -2293,7 +2276,6 @@ Parameter represents a set value for the scope. | `source_scheme` | `none` | | `source_scheme` | `data` | -<<<<<<< HEAD ## codersdk.PostWorkspaceAgentVersionRequest ```json @@ -2326,8 +2308,6 @@ Parameter represents a set value for the scope. | `healths` | object | false | | Healths is a map of the workspace app name and the health of the app. | | » `[any property]` | string | false | | | -======= ->>>>>>> main ## codersdk.PprofConfig ```json @@ -3002,11 +2982,7 @@ Parameter represents a set value for the scope. ```json { -<<<<<<< HEAD - "hash": "string" -======= "hash": "19686d84-b10d-4f90-b18e-84fd3fa038fd" ->>>>>>> main } ``` @@ -3913,7 +3889,6 @@ Parameter represents a set value for the scope. ### Properties _None_ -<<<<<<< HEAD ## tailcfg.DERPMap @@ -4063,5 +4038,3 @@ It corresponds to the legacy derpN.tailscale.com hostnames used by older clients RegionIDs must be non-zero, positive, and guaranteed to fit in a JavaScript number. RegionIDs in range 900-999 are reserved for end users to run their own DERP nodes.| |`regionName`|string|false||Regionname is a long English name for the region: "New York City", "San Francisco", "Singapore", "Frankfurt", etc.| -======= ->>>>>>> main diff --git a/docs/manifest.json b/docs/manifest.json index f71a99d85f2e8..079735f2800bb 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -362,7 +362,6 @@ "path": "./api/parameters.md" }, { -<<<<<<< HEAD "title": "Agents", "path": "./api/agents.md" }, @@ -371,8 +370,6 @@ "path": "./api/builds.md" }, { -======= ->>>>>>> main "title": "Schemas", "path": "./api/schemas.md" } From e314c243f9de2add15ea51601390e9aa30f59528 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Wed, 4 Jan 2023 11:29:50 +0100 Subject: [PATCH 16/36] x-apidocgen --- coderd/apidoc/docs.go | 3 +++ coderd/apidoc/swagger.json | 3 +++ coderd/workspaceagents.go | 1 + 3 files changed, 7 insertions(+) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 1e00cda9d61ac..907ea117126b1 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -1205,6 +1205,9 @@ const docTemplate = `{ "200": { "description": "OK" } + }, + "x-apidocgen": { + "skip": true } } }, diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 304cac3b05ee9..e78c98d53b608 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -1041,6 +1041,9 @@ "200": { "description": "OK" } + }, + "x-apidocgen": { + "skip": true } } }, diff --git a/coderd/workspaceagents.go b/coderd/workspaceagents.go index 10586ed7a37ba..f078655b37b07 100644 --- a/coderd/workspaceagents.go +++ b/coderd/workspaceagents.go @@ -154,6 +154,7 @@ func (api *API) workspaceAgentMetadata(rw http.ResponseWriter, r *http.Request) // @Param request body codersdk.PostWorkspaceAgentVersionRequest true "Version request" // @Success 200 // @Router /workspaceagents/me/version [post] +// @x-apidocgen {"skip": true} func (api *API) postWorkspaceAgentVersion(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() workspaceAgent := httpmw.WorkspaceAgent(r) From 97cd7ace66bcf132d87d592714f684a3f57e5f99 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Wed, 4 Jan 2023 11:43:22 +0100 Subject: [PATCH 17/36] NullTime hack not needed anymore --- scripts/apidocgen/markdown-template/main.dot | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/scripts/apidocgen/markdown-template/main.dot b/scripts/apidocgen/markdown-template/main.dot index 59236d94a9fbd..0fd9e25421288 100644 --- a/scripts/apidocgen/markdown-template/main.dot +++ b/scripts/apidocgen/markdown-template/main.dot @@ -92,11 +92,7 @@ > This page is incomplete, stay tuned. -{{ for (var s in data.components.schemas) { - if (s == "codersdk.NullTime") { - continue; - } -}} +{{ for (var s in data.components.schemas) { }} {{ var origSchema = data.components.schemas[s]; }} {{ var schema = data.api.components.schemas[s]; }} From ae06598c9f37fed78427efe22dffe93c100053c3 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Wed, 4 Jan 2023 12:27:06 +0100 Subject: [PATCH 18/36] Fix: x-apidocgen --- coderd/apidoc/docs.go | 1 + coderd/apidoc/swagger.json | 1 + codersdk/workspaceagents.go | 1 + docs/api/agents.md | 35 ------------------- docs/api/schemas.md | 14 -------- scripts/apidocgen/markdown-template/main.dot | 11 ++++-- .../apidocgen/markdown-template/operation.dot | 6 ++++ 7 files changed, 17 insertions(+), 52 deletions(-) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 907ea117126b1..41aeca263f6b0 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -2796,6 +2796,7 @@ const docTemplate = `{ } }, "codersdk.PostWorkspaceAgentVersionRequest": { + "description": "x-apidocgen:skip", "type": "object", "properties": { "version": { diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index e78c98d53b608..d9c4cd7be78c6 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -2516,6 +2516,7 @@ } }, "codersdk.PostWorkspaceAgentVersionRequest": { + "description": "x-apidocgen:skip", "type": "object", "properties": { "version": { diff --git a/codersdk/workspaceagents.go b/codersdk/workspaceagents.go index cd4c237616607..bb8ce62406f12 100644 --- a/codersdk/workspaceagents.go +++ b/codersdk/workspaceagents.go @@ -115,6 +115,7 @@ type WorkspaceAgentConnectionInfo struct { } // @typescript-ignore PostWorkspaceAgentVersionRequest +// @Description x-apidocgen:skip type PostWorkspaceAgentVersionRequest struct { Version string `json:"version"` } diff --git a/docs/api/agents.md b/docs/api/agents.md index d001d5309d67c..8ff2ee9036d2a 100644 --- a/docs/api/agents.md +++ b/docs/api/agents.md @@ -437,38 +437,3 @@ 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 by means of one of the following methods: **CoderSessionToken**. - -## Submit workspace agent version - -### Code samples - -```shell -# Example request using curl -curl -X POST http://coder-server:8080/api/v2/workspaceagents/me/version \ - -H 'Content-Type: application/json' \ - -H 'Coder-Session-Token: API_KEY' -``` - -`POST /workspaceagents/me/version` - -> Body parameter - -```json -{ - "version": "string" -} -``` - -### Parameters - -| Name | In | Type | Required | Description | -| ------ | ---- | ------------------------------------------------------------------------------------------------ | -------- | --------------- | -| `body` | body | [codersdk.PostWorkspaceAgentVersionRequest](schemas.md#codersdkpostworkspaceagentversionrequest) | true | Version request | - -### 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 by means of one of the following methods: **CoderSessionToken**. diff --git a/docs/api/schemas.md b/docs/api/schemas.md index 79cab87aef2c4..2e3d91cf5de22 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -2276,20 +2276,6 @@ Parameter represents a set value for the scope. | `source_scheme` | `none` | | `source_scheme` | `data` | -## codersdk.PostWorkspaceAgentVersionRequest - -```json -{ - "version": "string" -} -``` - -### Properties - -| Name | Type | Required | Restrictions | Description | -| --------- | ------ | -------- | ------------ | ----------- | -| `version` | string | false | | | - ## codersdk.PostWorkspaceAppHealthsRequest ```json diff --git a/scripts/apidocgen/markdown-template/main.dot b/scripts/apidocgen/markdown-template/main.dot index 0fd9e25421288..f2eea883eff57 100644 --- a/scripts/apidocgen/markdown-template/main.dot +++ b/scripts/apidocgen/markdown-template/main.dot @@ -92,9 +92,14 @@ > This page is incomplete, stay tuned. -{{ for (var s in data.components.schemas) { }} -{{ var origSchema = data.components.schemas[s]; }} -{{ var schema = data.api.components.schemas[s]; }} +{{ for (var s in data.components.schemas) { + var origSchema = data.components.schemas[s]; + var schema = data.api.components.schemas[s]; + + if (schema.description && schema.description.startsWith("x-apidocgen:skip")) { + continue; + } +}} {{= data.tags.section }} ## {{=s}} diff --git a/scripts/apidocgen/markdown-template/operation.dot b/scripts/apidocgen/markdown-template/operation.dot index 8e8129757c843..57856444b3eb7 100644 --- a/scripts/apidocgen/markdown-template/operation.dot +++ b/scripts/apidocgen/markdown-template/operation.dot @@ -18,6 +18,12 @@ ## {{= data.operationUniqueName}} +{{ + if (data.operation['x-apidocgen'] && data.operation['x-apidocgen'].skip) { + return ""; + } +}} + {{ data.methodUpper = data.method.verb.toUpperCase(); }} {{ data.url = data.utils.slashes(data.baseUrl + data.method.path); }} {{ data.parameters = data.operation.parameters; }} From 7aa0f65857611cbc64c5491908529c21c3aa9a18 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Wed, 4 Jan 2023 16:09:27 +0100 Subject: [PATCH 19/36] Members --- coderd/apidoc/docs.go | 335 +++++++++++++++++++++++++++-- coderd/apidoc/swagger.json | 311 +++++++++++++++++++++++++-- coderd/members.go | 11 + coderd/organizations.go | 4 +- coderd/roles.go | 9 + coderd/templates.go | 18 +- coderd/templateversions.go | 35 +++- coderd/workspaces.go | 7 +- codersdk/organizationmember.go | 8 +- docs/api/members.md | 112 ++++++++++ docs/api/organizations.md | 10 +- docs/api/schemas.md | 85 ++++++++ docs/api/templates.md | 370 ++++++++++++++++++++++++++------- docs/api/workspaces.md | 10 +- docs/manifest.json | 8 +- 15 files changed, 1195 insertions(+), 138 deletions(-) create mode 100644 docs/api/members.md diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 60ecf9c4e9845..e58a7edd1150f 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -414,7 +414,7 @@ const docTemplate = `{ } } }, - "/organizations/{id}": { + "/organizations/{organization}": { "get": { "security": [ { @@ -434,7 +434,7 @@ const docTemplate = `{ "type": "string", "format": "uuid", "description": "Organization ID", - "name": "id", + "name": "organization", "in": "path", "required": true } @@ -449,8 +449,46 @@ const docTemplate = `{ } } }, - "/organizations/{organization-id}/templates/": { - "post": { + "/organizations/{organization}/members/roles": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Members" + ], + "summary": "Get member roles by organization", + "operationId": "get-member-roles-by-organization", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.AssignableRoles" + } + } + } + } + } + }, + "/organizations/{organization}/members/{user}/roles": { + "put": { "security": [ { "CoderSessionToken": [] @@ -463,24 +501,31 @@ const docTemplate = `{ "application/json" ], "tags": [ - "Templates" + "Members" ], - "summary": "Create template by organization", - "operationId": "create-template-by-organization", + "summary": "Assign role to organization member", + "operationId": "assign-role-to-organization-member", "parameters": [ { - "description": "Request body", + "description": "Update roles request", "name": "request", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/codersdk.CreateTemplateRequest" + "$ref": "#/definitions/codersdk.UpdateRoles" } }, { "type": "string", "description": "Organization ID", - "name": "organization-id", + "name": "organization", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Username, UUID, or me", + "name": "user", "in": "path", "required": true } @@ -489,7 +534,7 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/codersdk.Template" + "$ref": "#/definitions/codersdk.OrganizationMember" } } } @@ -508,8 +553,8 @@ const docTemplate = `{ "tags": [ "Workspaces" ], - "summary": "Create workspace by organization", - "operationId": "create-workspace-by-organization", + "summary": "Create user workspace by organization", + "operationId": "create-user-workspace-by-organization", "parameters": [ { "type": "string", @@ -521,7 +566,7 @@ const docTemplate = `{ }, { "type": "string", - "description": "Username", + "description": "Username, UUID, or me", "name": "user", "in": "path", "required": true @@ -573,9 +618,91 @@ const docTemplate = `{ } } } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Create template by organization", + "operationId": "create-template-by-organization", + "parameters": [ + { + "description": "Request body", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateTemplateRequest" + } + }, + { + "type": "string", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Template" + } + } + } + } + }, + "/organizations/{organization}/templates/examples": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Get template examples by organization", + "operationId": "get-template-examples-by-organization", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.TemplateExample" + } + } + } + } } }, - "/organizations/{organization}/templates/{template-name}": { + "/organizations/{organization}/templates/{templatename}": { "get": { "security": [ { @@ -602,7 +729,7 @@ const docTemplate = `{ { "type": "string", "description": "Template name", - "name": "template-name", + "name": "templatename", "in": "path", "required": true } @@ -617,6 +744,95 @@ const docTemplate = `{ } } }, + "/organizations/{organization}/templateversions": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Create template version by organization", + "operationId": "create-template-version-by-organization", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + }, + { + "description": "Create template version request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateTemplateVersionDryRunRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.TemplateVersion" + } + } + } + } + }, + "/organizations/{organization}/templateversions/{templateversionname}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Get previous template version by organization and name", + "operationId": "get-previous-template-version-by-organization-and-name", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Template version name", + "name": "templateversionname", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.TemplateVersion" + } + } + } + } + }, "/parameters/{scope}/{id}": { "get": { "security": [ @@ -997,7 +1213,7 @@ const docTemplate = `{ } } }, - "/templates/{id}/versions/{name}": { + "/templates/{id}/versions/{templateversionname}": { "get": { "security": [ { @@ -1023,8 +1239,8 @@ const docTemplate = `{ }, { "type": "string", - "description": "Template name", - "name": "name", + "description": "Template version name", + "name": "templateversionname", "in": "path", "required": true } @@ -2554,6 +2770,20 @@ const docTemplate = `{ } } }, + "codersdk.AssignableRoles": { + "type": "object", + "properties": { + "assignable": { + "type": "boolean" + }, + "display_name": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, "codersdk.AuditDiff": { "type": "object", "additionalProperties": { @@ -3446,6 +3676,33 @@ const docTemplate = `{ } } }, + "codersdk.OrganizationMember": { + "type": "object", + "properties": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "organization_id": { + "type": "string", + "format": "uuid" + }, + "roles": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Role" + } + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "user_id": { + "type": "string", + "format": "uuid" + } + } + }, "codersdk.Parameter": { "description": "Parameter represents a set value for the scope.", "type": "object", @@ -3888,6 +4145,35 @@ const docTemplate = `{ } } }, + "codersdk.TemplateExample": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "id": { + "type": "string" + }, + "markdown": { + "type": "string" + }, + "name": { + "type": "string" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "url": { + "type": "string" + } + } + }, "codersdk.TemplateVersion": { "type": "object", "properties": { @@ -3980,6 +4266,17 @@ const docTemplate = `{ } } }, + "codersdk.UpdateRoles": { + "type": "object", + "properties": { + "roles": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, "codersdk.UpdateWorkspaceAutostartRequest": { "type": "object", "properties": { diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index a898bcc954c3a..70af1a888e6f5 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -356,7 +356,7 @@ } } }, - "/organizations/{id}": { + "/organizations/{organization}": { "get": { "security": [ { @@ -372,7 +372,7 @@ "type": "string", "format": "uuid", "description": "Organization ID", - "name": "id", + "name": "organization", "in": "path", "required": true } @@ -387,8 +387,42 @@ } } }, - "/organizations/{organization-id}/templates/": { - "post": { + "/organizations/{organization}/members/roles": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Members"], + "summary": "Get member roles by organization", + "operationId": "get-member-roles-by-organization", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.AssignableRoles" + } + } + } + } + } + }, + "/organizations/{organization}/members/{user}/roles": { + "put": { "security": [ { "CoderSessionToken": [] @@ -396,23 +430,30 @@ ], "consumes": ["application/json"], "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Create template by organization", - "operationId": "create-template-by-organization", + "tags": ["Members"], + "summary": "Assign role to organization member", + "operationId": "assign-role-to-organization-member", "parameters": [ { - "description": "Request body", + "description": "Update roles request", "name": "request", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/codersdk.CreateTemplateRequest" + "$ref": "#/definitions/codersdk.UpdateRoles" } }, { "type": "string", "description": "Organization ID", - "name": "organization-id", + "name": "organization", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Username, UUID, or me", + "name": "user", "in": "path", "required": true } @@ -421,7 +462,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/codersdk.Template" + "$ref": "#/definitions/codersdk.OrganizationMember" } } } @@ -436,8 +477,8 @@ ], "produces": ["application/json"], "tags": ["Workspaces"], - "summary": "Create workspace by organization", - "operationId": "create-workspace-by-organization", + "summary": "Create user workspace by organization", + "operationId": "create-user-workspace-by-organization", "parameters": [ { "type": "string", @@ -449,7 +490,7 @@ }, { "type": "string", - "description": "Username", + "description": "Username, UUID, or me", "name": "user", "in": "path", "required": true @@ -497,9 +538,81 @@ } } } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Create template by organization", + "operationId": "create-template-by-organization", + "parameters": [ + { + "description": "Request body", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateTemplateRequest" + } + }, + { + "type": "string", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Template" + } + } + } + } + }, + "/organizations/{organization}/templates/examples": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get template examples by organization", + "operationId": "get-template-examples-by-organization", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.TemplateExample" + } + } + } + } } }, - "/organizations/{organization}/templates/{template-name}": { + "/organizations/{organization}/templates/{templatename}": { "get": { "security": [ { @@ -522,7 +635,7 @@ { "type": "string", "description": "Template name", - "name": "template-name", + "name": "templatename", "in": "path", "required": true } @@ -537,6 +650,85 @@ } } }, + "/organizations/{organization}/templateversions": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Create template version by organization", + "operationId": "create-template-version-by-organization", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + }, + { + "description": "Create template version request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateTemplateVersionDryRunRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.TemplateVersion" + } + } + } + } + }, + "/organizations/{organization}/templateversions/{templateversionname}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get previous template version by organization and name", + "operationId": "get-previous-template-version-by-organization-and-name", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Template version name", + "name": "templateversionname", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.TemplateVersion" + } + } + } + } + }, "/parameters/{scope}/{id}": { "get": { "security": [ @@ -865,7 +1057,7 @@ } } }, - "/templates/{id}/versions/{name}": { + "/templates/{id}/versions/{templateversionname}": { "get": { "security": [ { @@ -887,8 +1079,8 @@ }, { "type": "string", - "description": "Template name", - "name": "name", + "description": "Template version name", + "name": "templateversionname", "in": "path", "required": true } @@ -2252,6 +2444,20 @@ } } }, + "codersdk.AssignableRoles": { + "type": "object", + "properties": { + "assignable": { + "type": "boolean" + }, + "display_name": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, "codersdk.AuditDiff": { "type": "object", "additionalProperties": { @@ -3104,6 +3310,33 @@ } } }, + "codersdk.OrganizationMember": { + "type": "object", + "properties": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "organization_id": { + "type": "string", + "format": "uuid" + }, + "roles": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Role" + } + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "user_id": { + "type": "string", + "format": "uuid" + } + } + }, "codersdk.Parameter": { "description": "Parameter represents a set value for the scope.", "type": "object", @@ -3520,6 +3753,35 @@ } } }, + "codersdk.TemplateExample": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "id": { + "type": "string" + }, + "markdown": { + "type": "string" + }, + "name": { + "type": "string" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "url": { + "type": "string" + } + } + }, "codersdk.TemplateVersion": { "type": "object", "properties": { @@ -3610,6 +3872,17 @@ } } }, + "codersdk.UpdateRoles": { + "type": "object", + "properties": { + "roles": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, "codersdk.UpdateWorkspaceAutostartRequest": { "type": "object", "properties": { diff --git a/coderd/members.go b/coderd/members.go index 2ae7fa9de6469..9141cadb6a0b3 100644 --- a/coderd/members.go +++ b/coderd/members.go @@ -16,6 +16,17 @@ import ( "github.com/coder/coder/codersdk" ) +// @Summary Assign role to organization member +// @ID assign-role-to-organization-member +// @Security CoderSessionToken +// @Accept json +// @Produce json +// @Tags Members +// @Param request body codersdk.UpdateRoles true "Update roles request" +// @Param organization path string true "Organization ID" +// @Param user path string true "Username, UUID, or me" +// @Success 200 {object} codersdk.OrganizationMember +// @Router /organizations/{organization}/members/{user}/roles [put] func (api *API) putMemberRoles(rw http.ResponseWriter, r *http.Request) { var ( ctx = r.Context() diff --git a/coderd/organizations.go b/coderd/organizations.go index ddbd38ac3d785..84bf1197348dd 100644 --- a/coderd/organizations.go +++ b/coderd/organizations.go @@ -21,9 +21,9 @@ import ( // @Security CoderSessionToken // @Produce json // @Tags Organizations -// @Param id path string true "Organization ID" format(uuid) +// @Param organization path string true "Organization ID" format(uuid) // @Success 200 {object} codersdk.Organization -// @Router /organizations/{id} [get] +// @Router /organizations/{organization} [get] func (api *API) organization(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() organization := httpmw.OrganizationParam(r) diff --git a/coderd/roles.go b/coderd/roles.go index 4e5ae05d99470..9eb1518d9ec6e 100644 --- a/coderd/roles.go +++ b/coderd/roles.go @@ -23,6 +23,15 @@ func (api *API) assignableSiteRoles(rw http.ResponseWriter, r *http.Request) { httpapi.Write(ctx, rw, http.StatusOK, assignableRoles(actorRoles.Roles, roles)) } +// @Summary Get member roles by organization +// @ID get-member-roles-by-organization +// @Security CoderSessionToken +// @Produce json +// @Tags Members +// @Param organization path string true "Organization ID" format(uuid) +// @Success 200 {array} codersdk.AssignableRoles +// @Router /organizations/{organization}/members/roles [get] +// // assignableSiteRoles returns all site wide roles that can be assigned. func (api *API) assignableOrgRoles(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() diff --git a/coderd/templates.go b/coderd/templates.go index a7680355ee05d..0f2f25008383d 100644 --- a/coderd/templates.go +++ b/coderd/templates.go @@ -149,9 +149,9 @@ func (api *API) deleteTemplate(rw http.ResponseWriter, r *http.Request) { // @Produce json // @Tags Templates // @Param request body codersdk.CreateTemplateRequest true "Request body" -// @Param organization-id path string true "Organization ID" +// @Param organization path string true "Organization ID" // @Success 200 {object} codersdk.Template -// @Router /organizations/{organization-id}/templates/ [post] +// @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) { @@ -347,7 +347,7 @@ func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Reque // @Produce json // @Tags Templates // @Param organization path string true "Organization ID" format(uuid) -// @Success 200 {object} []codersdk.Template +// @Success 200 {array} codersdk.Template // @Router /organizations/{organization}/templates [get] func (api *API) templatesByOrganization(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() @@ -413,9 +413,9 @@ func (api *API) templatesByOrganization(rw http.ResponseWriter, r *http.Request) // @Produce json // @Tags Templates // @Param organization path string true "Organization ID" format(uuid) -// @Param template-name path string true "Template name" +// @Param templatename path string true "Template name" // @Success 200 {object} codersdk.Template -// @Router /organizations/{organization}/templates/{template-name} [get] +// @Router /organizations/{organization}/templates/{templatename} [get] func (api *API) templateByOrganizationAndName(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() organization := httpmw.OrganizationParam(r) @@ -625,6 +625,14 @@ func (api *API) templateDAUs(rw http.ResponseWriter, r *http.Request) { httpapi.Write(ctx, rw, http.StatusOK, resp) } +// @Summary Get template examples by organization +// @ID get-template-examples-by-organization +// @Security CoderSessionToken +// @Produce json +// @Tags Templates +// @Param organization path string true "Organization ID" format(uuid) +// @Success 200 {array} codersdk.TemplateExample +// @Router /organizations/{organization}/templates/examples [get] func (api *API) templateExamples(rw http.ResponseWriter, r *http.Request) { var ( ctx = r.Context() diff --git a/coderd/templateversions.go b/coderd/templateversions.go index 9a6dc0d817583..dfff89b56f5a6 100644 --- a/coderd/templateversions.go +++ b/coderd/templateversions.go @@ -646,9 +646,9 @@ func (api *API) templateVersionsByTemplate(rw http.ResponseWriter, r *http.Reque // @Produce json // @Tags Templates // @Param id path string true "Template ID" format(uuid) -// @Param name path string true "Template name" +// @Param templateversionname path string true "Template version name" // @Success 200 {array} codersdk.TemplateVersion -// @Router /templates/{id}/versions/{name} [get] +// @Router /templates/{id}/versions/{templateversionname} [get] func (api *API) templateVersionByName(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() template := httpmw.TemplateParam(r) @@ -699,6 +699,15 @@ func (api *API) templateVersionByName(rw http.ResponseWriter, r *http.Request) { httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(templateVersion, convertProvisionerJob(job), user)) } +// @Summary Get template version by organization and name +// @ID get-template-version-by-organization-and-name +// @Security CoderSessionToken +// @Produce json +// @Tags Templates +// @Param organization path string true "Organization ID" format(uuid) +// @Param templateversionname path string true "Template version name" +// @Success 200 {object} codersdk.TemplateVersion +// @Router /organizations/{organization}/templateversions/{templateversionname} [get] func (api *API) templateVersionByOrganizationAndName(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() organization := httpmw.OrganizationParam(r) @@ -741,6 +750,15 @@ func (api *API) templateVersionByOrganizationAndName(rw http.ResponseWriter, r * httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(templateVersion, convertProvisionerJob(job), user)) } +// @Summary Get previous template version by organization and name +// @ID get-previous-template-version-by-organization-and-name +// @Security CoderSessionToken +// @Produce json +// @Tags Templates +// @Param organization path string true "Organization ID" format(uuid) +// @Param templateversionname path string true "Template version name" +// @Success 200 {object} codersdk.TemplateVersion +// @Router /organizations/{organization}/templateversions/{templateversionname} [get] func (api *API) previousTemplateVersionByOrganizationAndName(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() organization := httpmw.OrganizationParam(r) @@ -890,7 +908,18 @@ func (api *API) patchActiveTemplateVersion(rw http.ResponseWriter, r *http.Reque }) } -// Creates a new version of a template. An import job is queued to parse the storage method provided. +// @Summary Create template version by organization +// @ID create-template-version-by-organization +// @Security CoderSessionToken +// @Accept json +// @Produce json +// @Tags Templates +// @Param organization path string true "Organization ID" format(uuid) +// @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() diff --git a/coderd/workspaces.go b/coderd/workspaces.go index 23e605b298de1..6edd0d13c629b 100644 --- a/coderd/workspaces.go +++ b/coderd/workspaces.go @@ -266,15 +266,16 @@ func (api *API) workspaceByOwnerAndName(rw http.ResponseWriter, r *http.Request) )) } -// @Summary Create workspace by organization -// @ID create-workspace-by-organization +// @Summary Create user workspace by organization +// @ID create-user-workspace-by-organization // @Security CoderSessionToken // @Produce json // @Tags Workspaces // @Param organization path string true "Organization ID" format(uuid) -// @Param user path string true "Username" +// @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 ( diff --git a/codersdk/organizationmember.go b/codersdk/organizationmember.go index e35280ffa7e75..4ec90fb29cbde 100644 --- a/codersdk/organizationmember.go +++ b/codersdk/organizationmember.go @@ -7,9 +7,9 @@ import ( ) type OrganizationMember struct { - UserID uuid.UUID `db:"user_id" json:"user_id"` - OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"` - CreatedAt time.Time `db:"created_at" json:"created_at"` - UpdatedAt time.Time `db:"updated_at" json:"updated_at"` + UserID uuid.UUID `db:"user_id" json:"user_id" format:"uuid"` + OrganizationID uuid.UUID `db:"organization_id" json:"organization_id" format:"uuid"` + CreatedAt time.Time `db:"created_at" json:"created_at" format:"date-time"` + UpdatedAt time.Time `db:"updated_at" json:"updated_at" format:"date-time"` Roles []Role `db:"roles" json:"roles"` } diff --git a/docs/api/members.md b/docs/api/members.md new file mode 100644 index 0000000000000..519101c732979 --- /dev/null +++ b/docs/api/members.md @@ -0,0 +1,112 @@ +# Members + +> This page is incomplete, stay tuned. + +## Get member roles by organization + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/members/roles \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /organizations/{organization}/members/roles` + +### Parameters + +| Name | In | Type | Required | Description | +| -------------- | ---- | ------------ | -------- | --------------- | +| `organization` | path | string(uuid) | true | Organization ID | + +### Example responses + +> 200 Response + +```json +[ + { + "assignable": true, + "display_name": "string", + "name": "string" + } +] +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ----------------------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | array of [codersdk.AssignableRoles](schemas.md#codersdkassignableroles) | + +

Response Schema

+ +Status Code **200** + +| Name | Type | Required | Restrictions | Description | +| ---------------- | ------- | -------- | ------------ | ----------- | +| `[array item]` | array | false | | | +| `» assignable` | boolean | false | | | +| `» display_name` | string | false | | | +| `» name` | string | false | | | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Assign role to organization member + +### Code samples + +```shell +# Example request using curl +curl -X PUT http://coder-server:8080/api/v2/organizations/{organization}/members/{user}/roles \ + -H 'Content-Type: application/json' \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`PUT /organizations/{organization}/members/{user}/roles` + +> Body parameter + +```json +{ + "roles": ["string"] +} +``` + +### Parameters + +| Name | In | Type | Required | Description | +| -------------- | ---- | ------------------------------------------------------ | -------- | --------------------- | +| `organization` | path | string | true | Organization ID | +| `user` | path | string | true | Username, UUID, or me | +| `body` | body | [codersdk.UpdateRoles](schemas.md#codersdkupdateroles) | true | Update roles request | + +### Example responses + +> 200 Response + +```json +{ + "created_at": "2019-08-24T14:15:22Z", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "roles": [ + { + "display_name": "string", + "name": "string" + } + ], + "updated_at": "2019-08-24T14:15:22Z", + "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | -------------------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.OrganizationMember](schemas.md#codersdkorganizationmember) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. diff --git a/docs/api/organizations.md b/docs/api/organizations.md index 0fd429e8ceb03..bc0c6cbd07c1d 100644 --- a/docs/api/organizations.md +++ b/docs/api/organizations.md @@ -57,18 +57,18 @@ To perform this operation, you must be authenticated by means of one of the foll ```shell # Example request using curl -curl -X GET http://coder-server:8080/api/v2/organizations/{id} \ +curl -X GET http://coder-server:8080/api/v2/organizations/{organization} \ -H 'Accept: application/json' \ -H 'Coder-Session-Token: API_KEY' ``` -`GET /organizations/{id}` +`GET /organizations/{organization}` ### Parameters -| Name | In | Type | Required | Description | -| ---- | ---- | ------------ | -------- | --------------- | -| `id` | path | string(uuid) | true | Organization ID | +| Name | In | Type | Required | Description | +| -------------- | ---- | ------------ | -------- | --------------- | +| `organization` | path | string(uuid) | true | Organization ID | ### Example responses diff --git a/docs/api/schemas.md b/docs/api/schemas.md index 64f9a2077d564..87cffd52a8d78 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -90,6 +90,24 @@ | ----------------- | ------- | -------- | ------------ | ------------------------------------------------------------------------------ | | `report_interval` | integer | false | | Report interval is the duration after which the agent should send stats again. | +## codersdk.AssignableRoles + +```json +{ + "assignable": true, + "display_name": "string", + "name": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| -------------- | ------- | -------- | ------------ | ----------- | +| `assignable` | boolean | false | | | +| `display_name` | string | false | | | +| `name` | string | false | | | + ## codersdk.AuditDiff ```json @@ -2307,6 +2325,33 @@ CreateParameterRequest is a structure used to create a new parameter value for a | `name` | string | true | | | | `updated_at` | string | true | | | +## codersdk.OrganizationMember + +```json +{ + "created_at": "2019-08-24T14:15:22Z", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "roles": [ + { + "display_name": "string", + "name": "string" + } + ], + "updated_at": "2019-08-24T14:15:22Z", + "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ----------------- | --------------------------------------- | -------- | ------------ | ----------- | +| `created_at` | string | false | | | +| `organization_id` | string | false | | | +| `roles` | array of [codersdk.Role](#codersdkrole) | false | | | +| `updated_at` | string | false | | | +| `user_id` | string | false | | | + ## codersdk.Parameter ```json @@ -2989,6 +3034,32 @@ Parameter represents a set value for the scope. | --------- | ----------------------------------------------- | -------- | ------------ | ----------- | | `entries` | array of [codersdk.DAUEntry](#codersdkdauentry) | false | | | +## codersdk.TemplateExample + +```json +{ + "description": "string", + "icon": "string", + "id": "string", + "markdown": "string", + "name": "string", + "tags": ["string"], + "url": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ------------- | --------------- | -------- | ------------ | ----------- | +| `description` | string | false | | | +| `icon` | string | false | | | +| `id` | string | false | | | +| `markdown` | string | false | | | +| `name` | string | false | | | +| `tags` | array of string | false | | | +| `url` | string | false | | | + ## codersdk.TemplateVersion ```json @@ -3144,6 +3215,20 @@ Parameter represents a set value for the scope. | `url` | string | false | | URL to download the latest release of Coder. | | `version` | string | false | | Version is the semantic version for the latest release of Coder. | +## codersdk.UpdateRoles + +```json +{ + "roles": ["string"] +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ------- | --------------- | -------- | ------------ | ----------- | +| `roles` | array of string | false | | | + ## codersdk.UpdateWorkspaceAutostartRequest ```json diff --git a/docs/api/templates.md b/docs/api/templates.md index b5b618f7860d3..cb6b84a975890 100644 --- a/docs/api/templates.md +++ b/docs/api/templates.md @@ -2,19 +2,111 @@ > This page is incomplete, stay tuned. +## Get templates by organization + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/templates \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /organizations/{organization}/templates` + +### Parameters + +| Name | In | Type | Required | Description | +| -------------- | ---- | ------------ | -------- | --------------- | +| `organization` | path | string(uuid) | true | Organization ID | + +### Example responses + +> 200 Response + +```json +[ + { + "active_user_count": 0, + "active_version_id": "string", + "allow_user_cancel_workspace_jobs": true, + "build_time_stats": { + "property1": { + "p50": 123, + "p95": 146 + }, + "property2": { + "p50": 123, + "p95": 146 + } + }, + "created_at": "2019-08-24T14:15:22Z", + "created_by_id": "9377d689-01fb-4abf-8450-3368d2c1924f", + "created_by_name": "string", + "default_ttl_ms": 0, + "description": "string", + "display_name": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "provisioner": "string", + "updated_at": "2019-08-24T14:15:22Z", + "workspace_owner_count": 0 + } +] +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | --------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | array of [codersdk.Template](schemas.md#codersdktemplate) | + +

Response Schema

+ +Status Code **200** + +| Name | Type | Required | Restrictions | Description | +| ------------------------------------ | --------------------------------- | -------- | ------------ | ------------------------------------------ | +| `[array item]` | array | false | | | +| `» active_user_count` | integer | false | | ActiveUserCount is set to -1 when loading. | +| `» active_version_id` | string | false | | | +| `» allow_user_cancel_workspace_jobs` | boolean | false | | | +| `» build_time_stats` | `codersdk.TemplateBuildTimeStats` | false | | | +| `»» [any property]` | `codersdk.TransitionStats` | false | | | +| `»»» p50` | integer | false | | | +| `»»» p95` | integer | false | | | +| `» created_at` | string(date-time) | false | | | +| `» created_by_id` | string(uuid) | false | | | +| `» created_by_name` | string | false | | | +| `» default_ttl_ms` | integer | false | | | +| `» description` | string | false | | | +| `» display_name` | string | false | | | +| `» icon` | string | false | | | +| `» id` | string(uuid) | false | | | +| `» name` | string | false | | | +| `» organization_id` | string(uuid) | false | | | +| `» provisioner` | string | false | | | +| `» updated_at` | string(date-time) | false | | | +| `» workspace_owner_count` | integer | false | | | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + ## Create template by organization ### Code samples ```shell # Example request using curl -curl -X POST http://coder-server:8080/api/v2/organizations/{organization-id}/templates/ \ +curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/templates \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Coder-Session-Token: API_KEY' ``` -`POST /organizations/{organization-id}/templates/` +`POST /organizations/{organization}/templates` > Body parameter @@ -41,10 +133,10 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization-id}/tem ### Parameters -| Name | In | Type | Required | Description | -| ----------------- | ---- | -------------------------------------------------------------------------- | -------- | --------------- | -| `organization-id` | path | string | true | Organization ID | -| `body` | body | [codersdk.CreateTemplateRequest](schemas.md#codersdkcreatetemplaterequest) | true | Request body | +| Name | In | Type | Required | Description | +| -------------- | ---- | -------------------------------------------------------------------------- | -------- | --------------- | +| `organization` | path | string | true | Organization ID | +| `body` | body | [codersdk.CreateTemplateRequest](schemas.md#codersdkcreatetemplaterequest) | true | Request body | ### Example responses @@ -89,18 +181,18 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization-id}/tem To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. -## Get templates by organization +## Get template examples by organization ### Code samples ```shell # Example request using curl -curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/templates \ +curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/templates/examples \ -H 'Accept: application/json' \ -H 'Coder-Session-Token: API_KEY' ``` -`GET /organizations/{organization}/templates` +`GET /organizations/{organization}/templates/examples` ### Parameters @@ -115,69 +207,37 @@ curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/templat ```json [ { - "active_user_count": 0, - "active_version_id": "string", - "allow_user_cancel_workspace_jobs": true, - "build_time_stats": { - "property1": { - "p50": 123, - "p95": 146 - }, - "property2": { - "p50": 123, - "p95": 146 - } - }, - "created_at": "2019-08-24T14:15:22Z", - "created_by_id": "9377d689-01fb-4abf-8450-3368d2c1924f", - "created_by_name": "string", - "default_ttl_ms": 0, "description": "string", - "display_name": "string", "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "id": "string", + "markdown": "string", "name": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "provisioner": "string", - "updated_at": "2019-08-24T14:15:22Z", - "workspace_owner_count": 0 + "tags": ["string"], + "url": "string" } ] ``` ### Responses -| Status | Meaning | Description | Schema | -| ------ | ------------------------------------------------------- | ----------- | --------------------------------------------------------- | -| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | array of [codersdk.Template](schemas.md#codersdktemplate) | +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ----------------------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | array of [codersdk.TemplateExample](schemas.md#codersdktemplateexample) | -

Response Schema

+

Response Schema

Status Code **200** -| Name | Type | Required | Restrictions | Description | -| ------------------------------------ | --------------------------------- | -------- | ------------ | ------------------------------------------ | -| `[array item]` | array | false | | | -| `» active_user_count` | integer | false | | ActiveUserCount is set to -1 when loading. | -| `» active_version_id` | string | false | | | -| `» allow_user_cancel_workspace_jobs` | boolean | false | | | -| `» build_time_stats` | `codersdk.TemplateBuildTimeStats` | false | | | -| `»» [any property]` | `codersdk.TransitionStats` | false | | | -| `»»» p50` | integer | false | | | -| `»»» p95` | integer | false | | | -| `» created_at` | string(date-time) | false | | | -| `» created_by_id` | string(uuid) | false | | | -| `» created_by_name` | string | false | | | -| `» default_ttl_ms` | integer | false | | | -| `» description` | string | false | | | -| `» display_name` | string | false | | | -| `» icon` | string | false | | | -| `» id` | string(uuid) | false | | | -| `» name` | string | false | | | -| `» organization_id` | string(uuid) | false | | | -| `» provisioner` | string | false | | | -| `» updated_at` | string(date-time) | false | | | -| `» workspace_owner_count` | integer | false | | | +| Name | Type | Required | Restrictions | Description | +| --------------- | ------ | -------- | ------------ | ----------- | +| `[array item]` | array | false | | | +| `» description` | string | false | | | +| `» icon` | string | false | | | +| `» id` | string | false | | | +| `» markdown` | string | false | | | +| `» name` | string | false | | | +| `» tags` | array | false | | | +| `» url` | string | false | | | To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. @@ -187,19 +247,19 @@ To perform this operation, you must be authenticated by means of one of the foll ```shell # Example request using curl -curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/templates/{template-name} \ +curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/templates/{templatename} \ -H 'Accept: application/json' \ -H 'Coder-Session-Token: API_KEY' ``` -`GET /organizations/{organization}/templates/{template-name}` +`GET /organizations/{organization}/templates/{templatename}` ### Parameters -| Name | In | Type | Required | Description | -| --------------- | ---- | ------------ | -------- | --------------- | -| `organization` | path | string(uuid) | true | Organization ID | -| `template-name` | path | string | true | Template name | +| Name | In | Type | Required | Description | +| -------------- | ---- | ------------ | -------- | --------------- | +| `organization` | path | string(uuid) | true | Organization ID | +| `templatename` | path | string | true | Template name | ### Example responses @@ -244,6 +304,174 @@ curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/templat To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. +## Create template version by organization + +### Code samples + +```shell +# Example request using curl +curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/templateversions \ + -H 'Content-Type: application/json' \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`POST /organizations/{organization}/templateversions` + +> Body parameter + +```json +{ + "parameter_values": [ + { + "copy_from_parameter": "000e07d6-021d-446c-be14-48a9c20bca0b", + "destination_scheme": "none", + "name": "string", + "source_scheme": "none", + "source_value": "string" + } + ], + "workspace_name": "string" +} +``` + +### Parameters + +| Name | In | Type | Required | Description | +| -------------- | ---- | ---------------------------------------------------------------------------------------------------- | -------- | ------------------------------- | +| `organization` | path | string(uuid) | true | Organization ID | +| `body` | body | [codersdk.CreateTemplateVersionDryRunRequest](schemas.md#codersdkcreatetemplateversiondryrunrequest) | true | Create template version request | + +### Example responses + +> 201 Response + +```json +{ + "created_at": "2019-08-24T14:15:22Z", + "created_by": { + "avatar_url": "http://example.com", + "created_at": "2019-08-24T14:15:22Z", + "email": "string", + "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" + }, + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "job": { + "canceled_at": "2019-08-24T14:15:22Z", + "completed_at": "2019-08-24T14:15:22Z", + "created_at": "2019-08-24T14:15:22Z", + "error": "string", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" + }, + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "readme": "string", + "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", + "updated_at": "2019-08-24T14:15:22Z" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------------ | ----------- | -------------------------------------------------------------- | +| 201 | [Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) | Created | [codersdk.TemplateVersion](schemas.md#codersdktemplateversion) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Get previous template version by organization and name + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/templateversions/{templateversionname} \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /organizations/{organization}/templateversions/{templateversionname}` + +### Parameters + +| Name | In | Type | Required | Description | +| --------------------- | ---- | ------------ | -------- | --------------------- | +| `organization` | path | string(uuid) | true | Organization ID | +| `templateversionname` | path | string | true | Template version name | + +### Example responses + +> 200 Response + +```json +{ + "created_at": "2019-08-24T14:15:22Z", + "created_by": { + "avatar_url": "http://example.com", + "created_at": "2019-08-24T14:15:22Z", + "email": "string", + "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" + }, + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "job": { + "canceled_at": "2019-08-24T14:15:22Z", + "completed_at": "2019-08-24T14:15:22Z", + "created_at": "2019-08-24T14:15:22Z", + "error": "string", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" + }, + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "readme": "string", + "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", + "updated_at": "2019-08-24T14:15:22Z" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | -------------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.TemplateVersion](schemas.md#codersdktemplateversion) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + ## Get template metadata by ID ### Code samples @@ -642,19 +870,19 @@ To perform this operation, you must be authenticated by means of one of the foll ```shell # Example request using curl -curl -X GET http://coder-server:8080/api/v2/templates/{id}/versions/{name} \ +curl -X GET http://coder-server:8080/api/v2/templates/{id}/versions/{templateversionname} \ -H 'Accept: application/json' \ -H 'Coder-Session-Token: API_KEY' ``` -`GET /templates/{id}/versions/{name}` +`GET /templates/{id}/versions/{templateversionname}` ### Parameters -| Name | In | Type | Required | Description | -| ------ | ---- | ------------ | -------- | ------------- | -| `id` | path | string(uuid) | true | Template ID | -| `name` | path | string | true | Template name | +| Name | In | Type | Required | Description | +| --------------------- | ---- | ------------ | -------- | --------------------- | +| `id` | path | string(uuid) | true | Template ID | +| `templateversionname` | path | string | true | Template version name | ### Example responses diff --git a/docs/api/workspaces.md b/docs/api/workspaces.md index 9254214759b09..7220e8ccd754e 100644 --- a/docs/api/workspaces.md +++ b/docs/api/workspaces.md @@ -2,7 +2,7 @@ > This page is incomplete, stay tuned. -## Create workspace by organization +## Create user workspace by organization ### Code samples @@ -17,10 +17,10 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/member ### Parameters -| Name | In | Type | Required | Description | -| -------------- | ---- | ------------ | -------- | --------------- | -| `organization` | path | string(uuid) | true | Organization ID | -| `user` | path | string | true | Username | +| Name | In | Type | Required | Description | +| -------------- | ---- | ------------ | -------- | --------------------- | +| `organization` | path | string(uuid) | true | Organization ID | +| `user` | path | string | true | Username, UUID, or me | ### Example responses diff --git a/docs/manifest.json b/docs/manifest.json index 0d5a7ad0c4144..603771bedcb0b 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -354,13 +354,17 @@ "path": "./api/organizations.md" }, { - "title": "Templates", - "path": "./api/templates.md" + "title": "Members", + "path": "./api/members.md" }, { "title": "Workspaces", "path": "./api/workspaces.md" }, + { + "title": "Templates", + "path": "./api/templates.md" + }, { "title": "Parameters", "path": "./api/parameters.md" From b93398ec51b79f43efa10b4109f16b8d151c9e10 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Wed, 4 Jan 2023 16:14:58 +0100 Subject: [PATCH 20/36] Fixes --- coderd/apidoc/docs.go | 246 +++++++++++---- coderd/apidoc/swagger.json | 230 ++++++++++---- coderd/templateversions.go | 34 +- docs/api/templates.md | 628 ++++++++++++++++++++++++++++--------- 4 files changed, 855 insertions(+), 283 deletions(-) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index e58a7edd1150f..2429df3b8232a 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -792,6 +792,48 @@ const docTemplate = `{ } }, "/organizations/{organization}/templateversions/{templateversionname}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Get template version by organization and name", + "operationId": "get-template-version-by-organization-and-name", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Template version name", + "name": "templateversionname", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.TemplateVersion" + } + } + } + } + }, + "/organizations/{organization}/templateversions/{templateversionname}/previous": { "get": { "security": [ { @@ -1375,64 +1417,54 @@ const docTemplate = `{ } } }, - "/templateversions/{id}/resources": { + "/templateversions/{templateversionid}/dry-run/{jobid}": { "get": { "security": [ { "CoderSessionToken": [] } ], + "consumes": [ + "application/json" + ], "produces": [ "application/json" ], "tags": [ "Templates" ], - "summary": "Get template version logs by template version ID", - "operationId": "get-template-version-resources-by-template-version-id", + "summary": "Get template version dry-run by job ID", + "operationId": "get-template-version-dry-run-by-job-id", "parameters": [ { "type": "string", "format": "uuid", "description": "Template version ID", - "name": "id", + "name": "templateversionid", "in": "path", "required": true }, { - "type": "integer", - "description": "Before Unix timestamp", - "name": "before", - "in": "query" - }, - { - "type": "integer", - "description": "After Unix timestamp", - "name": "after", - "in": "query" - }, - { - "type": "boolean", - "description": "Follow log stream", - "name": "follow", - "in": "query" + "type": "string", + "format": "uuid", + "description": "Job ID", + "name": "jobid", + "in": "path", + "required": true } ], "responses": { "200": { "description": "OK", "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.ProvisionerJobLog" - } + "$ref": "#/definitions/codersdk.ProvisionerJob" } } } } }, - "/templateversions/{id}/schema": { - "get": { + "/templateversions/{templateversionid}/dry-run/{jobid}/cancel": { + "patch": { "security": [ { "CoderSessionToken": [] @@ -1444,8 +1476,8 @@ const docTemplate = `{ "tags": [ "Templates" ], - "summary": "Get template version schema by ID", - "operationId": "get-template-version-schema-by-id", + "summary": "Cancel template version dry-run by job ID", + "operationId": "cancel-template-version-dry-run-by-job-id", "parameters": [ { "type": "string", @@ -1460,33 +1492,27 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/parameter.ComputedValue" - } + "$ref": "#/definitions/codersdk.Response" } } } } }, - "/templateversions/{templateversionid}/dry-run/{jobid}": { + "/templateversions/{templateversionid}/dry-run/{jobid}/logs": { "get": { "security": [ { "CoderSessionToken": [] } ], - "consumes": [ - "application/json" - ], "produces": [ "application/json" ], "tags": [ "Templates" ], - "summary": "Get template version dry-run by job ID", - "operationId": "get-template-version-dry-run-by-job-id", + "summary": "Get template version dry-run logs by job ID", + "operationId": "get-template-version-dry-run-logs-by-job-id", "parameters": [ { "type": "string", @@ -1503,20 +1529,41 @@ const docTemplate = `{ "name": "jobid", "in": "path", "required": true + }, + { + "type": "integer", + "description": "Before Unix timestamp", + "name": "before", + "in": "query" + }, + { + "type": "integer", + "description": "After Unix timestamp", + "name": "after", + "in": "query" + }, + { + "type": "boolean", + "description": "Follow log stream", + "name": "follow", + "in": "query" } ], "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/codersdk.ProvisionerJob" + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.ProvisionerJobLog" + } } } } } }, - "/templateversions/{templateversionid}/dry-run/{jobid}/cancel": { - "patch": { + "/templateversions/{templateversionid}/dry-run/{jobid}/resources": { + "get": { "security": [ { "CoderSessionToken": [] @@ -1528,14 +1575,22 @@ const docTemplate = `{ "tags": [ "Templates" ], - "summary": "Cancel template version dry-run by job ID", - "operationId": "cancel-template-version-dry-run-by-job-id", + "summary": "Get template version dry-run resources by job ID", + "operationId": "get-template-version-dry-run-resources-by-job-id", "parameters": [ { "type": "string", "format": "uuid", "description": "Template version ID", - "name": "id", + "name": "templateversionid", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "Job ID", + "name": "jobid", "in": "path", "required": true } @@ -1544,13 +1599,16 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/codersdk.Response" + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceResource" + } } } } } }, - "/templateversions/{templateversionid}/dry-run/{jobid}/logs": { + "/templateversions/{templateversion}/logs": { "get": { "security": [ { @@ -1563,22 +1621,14 @@ const docTemplate = `{ "tags": [ "Templates" ], - "summary": "Get template version dry-run logs by job ID", - "operationId": "get-template-version-dry-run-logs-by-job-id", + "summary": "Get logs by template version", + "operationId": "get-logs-by-template-version", "parameters": [ { "type": "string", "format": "uuid", "description": "Template version ID", - "name": "templateversionid", - "in": "path", - "required": true - }, - { - "type": "string", - "format": "uuid", - "description": "Job ID", - "name": "jobid", + "name": "templateversion", "in": "path", "required": true }, @@ -1614,7 +1664,7 @@ const docTemplate = `{ } } }, - "/templateversions/{templateversionid}/dry-run/{jobid}/resources": { + "/templateversions/{templateversion}/parameters": { "get": { "security": [ { @@ -1627,22 +1677,52 @@ const docTemplate = `{ "tags": [ "Templates" ], - "summary": "Get template version dry-run resources by job ID", - "operationId": "get-template-version-dry-run-resources-by-job-id", + "summary": "Get parameters by template version", + "operationId": "get-parameters-by-template-version", "parameters": [ { "type": "string", "format": "uuid", "description": "Template version ID", - "name": "templateversionid", + "name": "templateversion", "in": "path", "required": true - }, + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/parameter.ComputedValue" + } + } + } + } + } + }, + "/templateversions/{templateversion}/resources": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Get resources by template version", + "operationId": "get-resources-by-template-version", + "parameters": [ { "type": "string", "format": "uuid", - "description": "Job ID", - "name": "jobid", + "description": "Template version ID", + "name": "templateversion", "in": "path", "required": true } @@ -1660,6 +1740,44 @@ const docTemplate = `{ } } }, + "/templateversions/{templateversion}/schema": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Get schema by template version", + "operationId": "get-schema-by-template-version", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversion", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.ParameterSchema" + } + } + } + } + } + }, "/updatecheck": { "get": { "produces": [ diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 70af1a888e6f5..d600ce601784a 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -692,6 +692,44 @@ } }, "/organizations/{organization}/templateversions/{templateversionname}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get template version by organization and name", + "operationId": "get-template-version-by-organization-and-name", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Template version name", + "name": "templateversionname", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.TemplateVersion" + } + } + } + } + }, + "/organizations/{organization}/templateversions/{templateversionname}/previous": { "get": { "security": [ { @@ -1201,60 +1239,48 @@ } } }, - "/templateversions/{id}/resources": { + "/templateversions/{templateversionid}/dry-run/{jobid}": { "get": { "security": [ { "CoderSessionToken": [] } ], + "consumes": ["application/json"], "produces": ["application/json"], "tags": ["Templates"], - "summary": "Get template version logs by template version ID", - "operationId": "get-template-version-resources-by-template-version-id", + "summary": "Get template version dry-run by job ID", + "operationId": "get-template-version-dry-run-by-job-id", "parameters": [ { "type": "string", "format": "uuid", "description": "Template version ID", - "name": "id", + "name": "templateversionid", "in": "path", "required": true }, { - "type": "integer", - "description": "Before Unix timestamp", - "name": "before", - "in": "query" - }, - { - "type": "integer", - "description": "After Unix timestamp", - "name": "after", - "in": "query" - }, - { - "type": "boolean", - "description": "Follow log stream", - "name": "follow", - "in": "query" + "type": "string", + "format": "uuid", + "description": "Job ID", + "name": "jobid", + "in": "path", + "required": true } ], "responses": { "200": { "description": "OK", "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.ProvisionerJobLog" - } + "$ref": "#/definitions/codersdk.ProvisionerJob" } } } } }, - "/templateversions/{id}/schema": { - "get": { + "/templateversions/{templateversionid}/dry-run/{jobid}/cancel": { + "patch": { "security": [ { "CoderSessionToken": [] @@ -1262,8 +1288,8 @@ ], "produces": ["application/json"], "tags": ["Templates"], - "summary": "Get template version schema by ID", - "operationId": "get-template-version-schema-by-id", + "summary": "Cancel template version dry-run by job ID", + "operationId": "cancel-template-version-dry-run-by-job-id", "parameters": [ { "type": "string", @@ -1278,27 +1304,23 @@ "200": { "description": "OK", "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/parameter.ComputedValue" - } + "$ref": "#/definitions/codersdk.Response" } } } } }, - "/templateversions/{templateversionid}/dry-run/{jobid}": { + "/templateversions/{templateversionid}/dry-run/{jobid}/logs": { "get": { "security": [ { "CoderSessionToken": [] } ], - "consumes": ["application/json"], "produces": ["application/json"], "tags": ["Templates"], - "summary": "Get template version dry-run by job ID", - "operationId": "get-template-version-dry-run-by-job-id", + "summary": "Get template version dry-run logs by job ID", + "operationId": "get-template-version-dry-run-logs-by-job-id", "parameters": [ { "type": "string", @@ -1315,20 +1337,41 @@ "name": "jobid", "in": "path", "required": true + }, + { + "type": "integer", + "description": "Before Unix timestamp", + "name": "before", + "in": "query" + }, + { + "type": "integer", + "description": "After Unix timestamp", + "name": "after", + "in": "query" + }, + { + "type": "boolean", + "description": "Follow log stream", + "name": "follow", + "in": "query" } ], "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/codersdk.ProvisionerJob" + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.ProvisionerJobLog" + } } } } } }, - "/templateversions/{templateversionid}/dry-run/{jobid}/cancel": { - "patch": { + "/templateversions/{templateversionid}/dry-run/{jobid}/resources": { + "get": { "security": [ { "CoderSessionToken": [] @@ -1336,14 +1379,22 @@ ], "produces": ["application/json"], "tags": ["Templates"], - "summary": "Cancel template version dry-run by job ID", - "operationId": "cancel-template-version-dry-run-by-job-id", + "summary": "Get template version dry-run resources by job ID", + "operationId": "get-template-version-dry-run-resources-by-job-id", "parameters": [ { "type": "string", "format": "uuid", "description": "Template version ID", - "name": "id", + "name": "templateversionid", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "Job ID", + "name": "jobid", "in": "path", "required": true } @@ -1352,13 +1403,16 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/codersdk.Response" + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceResource" + } } } } } }, - "/templateversions/{templateversionid}/dry-run/{jobid}/logs": { + "/templateversions/{templateversion}/logs": { "get": { "security": [ { @@ -1367,22 +1421,14 @@ ], "produces": ["application/json"], "tags": ["Templates"], - "summary": "Get template version dry-run logs by job ID", - "operationId": "get-template-version-dry-run-logs-by-job-id", + "summary": "Get logs by template version", + "operationId": "get-logs-by-template-version", "parameters": [ { "type": "string", "format": "uuid", "description": "Template version ID", - "name": "templateversionid", - "in": "path", - "required": true - }, - { - "type": "string", - "format": "uuid", - "description": "Job ID", - "name": "jobid", + "name": "templateversion", "in": "path", "required": true }, @@ -1418,7 +1464,7 @@ } } }, - "/templateversions/{templateversionid}/dry-run/{jobid}/resources": { + "/templateversions/{templateversion}/parameters": { "get": { "security": [ { @@ -1427,22 +1473,48 @@ ], "produces": ["application/json"], "tags": ["Templates"], - "summary": "Get template version dry-run resources by job ID", - "operationId": "get-template-version-dry-run-resources-by-job-id", + "summary": "Get parameters by template version", + "operationId": "get-parameters-by-template-version", "parameters": [ { "type": "string", "format": "uuid", "description": "Template version ID", - "name": "templateversionid", + "name": "templateversion", "in": "path", "required": true - }, + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/parameter.ComputedValue" + } + } + } + } + } + }, + "/templateversions/{templateversion}/resources": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get resources by template version", + "operationId": "get-resources-by-template-version", + "parameters": [ { "type": "string", "format": "uuid", - "description": "Job ID", - "name": "jobid", + "description": "Template version ID", + "name": "templateversion", "in": "path", "required": true } @@ -1460,6 +1532,40 @@ } } }, + "/templateversions/{templateversion}/schema": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get schema by template version", + "operationId": "get-schema-by-template-version", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversion", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.ParameterSchema" + } + } + } + } + } + }, "/updatecheck": { "get": { "produces": ["application/json"], diff --git a/coderd/templateversions.go b/coderd/templateversions.go index dfff89b56f5a6..e606d170a6601 100644 --- a/coderd/templateversions.go +++ b/coderd/templateversions.go @@ -132,14 +132,14 @@ func (api *API) patchCancelTemplateVersion(rw http.ResponseWriter, r *http.Reque }) } -// @Summary Get template version schema by template version ID -// @ID get-template-version-schema-by-template-version-id +// @Summary Get schema by template version +// @ID get-schema-by-template-version // @Security CoderSessionToken // @Produce json // @Tags Templates -// @Param id path string true "Template version ID" format(uuid) +// @Param templateversion path string true "Template version ID" format(uuid) // @Success 200 {array} codersdk.ParameterSchema -// @Router /templateversions/{id}/schema [get] +// @Router /templateversions/{templateversion}/schema [get] func (api *API) templateVersionSchema(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() var ( @@ -192,14 +192,14 @@ func (api *API) templateVersionSchema(rw http.ResponseWriter, r *http.Request) { httpapi.Write(ctx, rw, http.StatusOK, apiSchemas) } -// @Summary Get template version schema by ID -// @ID get-template-version-schema-by-id +// @Summary Get parameters by template version +// @ID get-parameters-by-template-version // @Security CoderSessionToken // @Produce json // @Tags Templates -// @Param id path string true "Template version ID" format(uuid) +// @Param templateversion path string true "Template version ID" format(uuid) // @Success 200 {array} parameter.ComputedValue -// @Router /templateversions/{id}/schema [get] +// @Router /templateversions/{templateversion}/parameters [get] func (api *API) templateVersionParameters(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() var ( @@ -758,7 +758,7 @@ func (api *API) templateVersionByOrganizationAndName(rw http.ResponseWriter, r * // @Param organization path string true "Organization ID" format(uuid) // @Param templateversionname path string true "Template version name" // @Success 200 {object} codersdk.TemplateVersion -// @Router /organizations/{organization}/templateversions/{templateversionname} [get] +// @Router /organizations/{organization}/templateversions/{templateversionname}/previous [get] func (api *API) previousTemplateVersionByOrganizationAndName(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() organization := httpmw.OrganizationParam(r) @@ -1204,14 +1204,14 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht httpapi.Write(ctx, rw, http.StatusCreated, convertTemplateVersion(templateVersion, convertProvisionerJob(provisionerJob), user)) } -// @Summary Get template version resources by template version ID -// @ID get-template-version-resources-by-template-version-id +// @Summary Get resources by template version +// @ID get-resources-by-template-version // @Security CoderSessionToken // @Produce json // @Tags Templates -// @Param id path string true "Template version ID" format(uuid) +// @Param templateversion path string true "Template version ID" format(uuid) // @Success 200 {array} codersdk.WorkspaceResource -// @Router /templateversions/{id}/resources [get] +// @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 @@ -1241,17 +1241,17 @@ func (api *API) templateVersionResources(rw http.ResponseWriter, r *http.Request api.provisionerJobResources(rw, r, job) } -// @Summary Get template version logs by template version ID -// @ID get-template-version-resources-by-template-version-id +// @Summary Get logs by template version +// @ID get-logs-by-template-version // @Security CoderSessionToken // @Produce json // @Tags Templates -// @Param id path string true "Template version ID" format(uuid) +// @Param templateversion path string true "Template version 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/{id}/resources [get] +// @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, diff --git a/docs/api/templates.md b/docs/api/templates.md index cb6b84a975890..e7c586d459b90 100644 --- a/docs/api/templates.md +++ b/docs/api/templates.md @@ -397,7 +397,7 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/templa To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. -## Get previous template version by organization and name +## Get template version by organization and name ### Code samples @@ -472,6 +472,81 @@ curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/templat To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. +## Get previous template version by organization and name + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/templateversions/{templateversionname}/previous \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /organizations/{organization}/templateversions/{templateversionname}/previous` + +### Parameters + +| Name | In | Type | Required | Description | +| --------------------- | ---- | ------------ | -------- | --------------------- | +| `organization` | path | string(uuid) | true | Organization ID | +| `templateversionname` | path | string | true | Template version name | + +### Example responses + +> 200 Response + +```json +{ + "created_at": "2019-08-24T14:15:22Z", + "created_by": { + "avatar_url": "http://example.com", + "created_at": "2019-08-24T14:15:22Z", + "email": "string", + "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" + }, + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "job": { + "canceled_at": "2019-08-24T14:15:22Z", + "completed_at": "2019-08-24T14:15:22Z", + "created_at": "2019-08-24T14:15:22Z", + "error": "string", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" + }, + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "readme": "string", + "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", + "updated_at": "2019-08-24T14:15:22Z" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | -------------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.TemplateVersion](schemas.md#codersdktemplateversion) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + ## Get template metadata by ID ### Code samples @@ -1179,145 +1254,6 @@ curl -X POST http://coder-server:8080/api/v2/templateversions/{id}/dry-run \ To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. -## Get template version logs by template version ID - -### Code samples - -```shell -# Example request using curl -curl -X GET http://coder-server:8080/api/v2/templateversions/{id}/resources \ - -H 'Accept: application/json' \ - -H 'Coder-Session-Token: API_KEY' -``` - -`GET /templateversions/{id}/resources` - -### Parameters - -| Name | In | Type | Required | Description | -| -------- | ----- | ------------ | -------- | --------------------- | -| `id` | path | string(uuid) | true | Template version ID | -| `before` | query | integer | false | Before Unix timestamp | -| `after` | query | integer | false | After Unix timestamp | -| `follow` | query | boolean | false | Follow log stream | - -### Example responses - -> 200 Response - -```json -[ - { - "created_at": "2019-08-24T14:15:22Z", - "id": 0, - "log_level": "trace", - "log_source": "string", - "output": "string", - "stage": "string" - } -] -``` - -### Responses - -| Status | Meaning | Description | Schema | -| ------ | ------------------------------------------------------- | ----------- | --------------------------------------------------------------------------- | -| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | array of [codersdk.ProvisionerJobLog](schemas.md#codersdkprovisionerjoblog) | - -

Response Schema

- -Status Code **200** - -| Name | Type | Required | Restrictions | Description | -| -------------- | ----------------- | -------- | ------------ | ----------- | -| `[array item]` | array | false | | | -| `» created_at` | string(date-time) | false | | | -| `» id` | integer | false | | | -| `» log_level` | string | false | | | -| `» log_source` | string | false | | | -| `» output` | string | false | | | -| `» stage` | string | false | | | - -#### Enumerated Values - -| Property | Value | -| ----------- | ------- | -| `log_level` | `trace` | -| `log_level` | `debug` | -| `log_level` | `info` | -| `log_level` | `warn` | -| `log_level` | `error` | - -To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. - -## Get template version schema by ID - -### Code samples - -```shell -# Example request using curl -curl -X GET http://coder-server:8080/api/v2/templateversions/{id}/schema \ - -H 'Accept: application/json' \ - -H 'Coder-Session-Token: API_KEY' -``` - -`GET /templateversions/{id}/schema` - -### Parameters - -| Name | In | Type | Required | Description | -| ---- | ---- | ------------ | -------- | ------------------- | -| `id` | path | string(uuid) | true | Template version ID | - -### Example responses - -> 200 Response - -```json -[ - { - "created_at": "string", - "default_source_value": true, - "destination_scheme": "string", - "id": "string", - "name": "string", - "schema_id": "string", - "scope": "string", - "scope_id": "string", - "source_scheme": "string", - "source_value": "string", - "updated_at": "string" - } -] -``` - -### Responses - -| Status | Meaning | Description | Schema | -| ------ | ------------------------------------------------------- | ----------- | --------------------------------------------------------------------- | -| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | array of [parameter.ComputedValue](schemas.md#parametercomputedvalue) | - -

Response Schema

- -Status Code **200** - -| Name | Type | Required | Restrictions | Description | -| ------------------------ | ------- | -------- | ------------ | ----------- | -| `[array item]` | array | false | | | -| `» created_at` | string | false | | | -| `» default_source_value` | boolean | false | | | -| `» destination_scheme` | string | false | | | -| `» id` | string | false | | | -| `» name` | string | false | | | -| `» schema_id` | string | false | | | -| `» scope` | string | false | | | -| `» scope_id` | string | false | | | -| `» source_scheme` | string | false | | | -| `» source_value` | string | false | | | -| `» updated_at` | string | false | | | - -To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. - ## Get template version dry-run by job ID ### Code samples @@ -1667,3 +1603,415 @@ Status Code **200** | `workspace_transition` | `delete` | To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Get logs by template version + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/logs \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /templateversions/{templateversion}/logs` + +### Parameters + +| Name | In | Type | Required | Description | +| ----------------- | ----- | ------------ | -------- | --------------------- | +| `templateversion` | path | string(uuid) | true | Template version ID | +| `before` | query | integer | false | Before Unix timestamp | +| `after` | query | integer | false | After Unix timestamp | +| `follow` | query | boolean | false | Follow log stream | + +### Example responses + +> 200 Response + +```json +[ + { + "created_at": "2019-08-24T14:15:22Z", + "id": 0, + "log_level": "trace", + "log_source": "string", + "output": "string", + "stage": "string" + } +] +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | --------------------------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | array of [codersdk.ProvisionerJobLog](schemas.md#codersdkprovisionerjoblog) | + +

Response Schema

+ +Status Code **200** + +| Name | Type | Required | Restrictions | Description | +| -------------- | ----------------- | -------- | ------------ | ----------- | +| `[array item]` | array | false | | | +| `» created_at` | string(date-time) | false | | | +| `» id` | integer | false | | | +| `» log_level` | string | false | | | +| `» log_source` | string | false | | | +| `» output` | string | false | | | +| `» stage` | string | false | | | + +#### Enumerated Values + +| Property | Value | +| ----------- | ------- | +| `log_level` | `trace` | +| `log_level` | `debug` | +| `log_level` | `info` | +| `log_level` | `warn` | +| `log_level` | `error` | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Get parameters by template version + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/parameters \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /templateversions/{templateversion}/parameters` + +### Parameters + +| Name | In | Type | Required | Description | +| ----------------- | ---- | ------------ | -------- | ------------------- | +| `templateversion` | path | string(uuid) | true | Template version ID | + +### Example responses + +> 200 Response + +```json +[ + { + "created_at": "string", + "default_source_value": true, + "destination_scheme": "string", + "id": "string", + "name": "string", + "schema_id": "string", + "scope": "string", + "scope_id": "string", + "source_scheme": "string", + "source_value": "string", + "updated_at": "string" + } +] +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | --------------------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | array of [parameter.ComputedValue](schemas.md#parametercomputedvalue) | + +

Response Schema

+ +Status Code **200** + +| Name | Type | Required | Restrictions | Description | +| ------------------------ | ------- | -------- | ------------ | ----------- | +| `[array item]` | array | false | | | +| `» created_at` | string | false | | | +| `» default_source_value` | boolean | false | | | +| `» destination_scheme` | string | false | | | +| `» id` | string | false | | | +| `» name` | string | false | | | +| `» schema_id` | string | false | | | +| `» scope` | string | false | | | +| `» scope_id` | string | false | | | +| `» source_scheme` | string | false | | | +| `» source_value` | string | false | | | +| `» updated_at` | string | false | | | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Get resources by template version + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/resources \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /templateversions/{templateversion}/resources` + +### Parameters + +| Name | In | Type | Required | Description | +| ----------------- | ---- | ------------ | -------- | ------------------- | +| `templateversion` | path | string(uuid) | true | Template version ID | + +### Example responses + +> 200 Response + +```json +[ + { + "agents": [ + { + "apps": [ + { + "command": "string", + "display_name": "string", + "external": true, + "health": "string", + "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" + } + ], + "created_at": "2019-08-24T14:15:22Z", + "daily_cost": 0, + "hide": true, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f", + "metadata": [ + { + "key": "string", + "sensitive": true, + "value": "string" + } + ], + "name": "string", + "type": "string", + "workspace_transition": "start" + } +] +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | --------------------------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | array of [codersdk.WorkspaceResource](schemas.md#codersdkworkspaceresource) | + +

Response Schema

+ +Status Code **200** + +| Name | Type | Required | Restrictions | Description | +| ------------------------------- | ---------------------- | -------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `[array item]` | array | false | | | +| `» agents` | array | false | | | +| `»» apps` | array | false | | | +| `»»» command` | string | false | | | +| `»»» display_name` | string | false | | DisplayName is a friendly name for the app. | +| `»»» external` | boolean | false | | External specifies whether the URL should be opened externally on
the client or not. | +| `»»» health` | string | false | | | +| `»»» healthcheck` | `codersdk.Healthcheck` | false | | | +| `»»»» interval` | integer | false | | Interval specifies the seconds between each health check. | +| `»»»» threshold` | integer | false | | Threshold specifies the number of consecutive failed health checks before returning "unhealthy". | +| `»»»» url` | string | false | | URL specifies the endpoint to check for the app health. | +| `»»» icon` | string | false | | Icon is a relative path or external URL that specifies
an icon to be displayed in the dashboard. | +| `»»» id` | string(uuid) | false | | | +| `»»» sharing_level` | string | false | | | +| `»»» slug` | string | false | | Slug is a unique identifier within the agent. | +| `»»» subdomain` | boolean | false | | Subdomain denotes whether the app should be accessed via a path on the
`coder server` or via a hostname-based dev URL. If this is set to true
and there is no app wildcard configured on the server, the app will not
be accessible in the UI. | +| `»»» url` | string | false | | URL is the address being proxied to inside the workspace.
If external is specified, this will be opened on the client. | +| `»» architecture` | string | false | | | +| `»» connection_timeout_seconds` | integer | false | | | +| `»» created_at` | string(date-time) | false | | | +| `»» directory` | string | false | | | +| `»» disconnected_at` | string(date-time) | false | | | +| `»» environment_variables` | object | false | | | +| `»»» [any property]` | string | false | | | +| `»» first_connected_at` | string(date-time) | false | | | +| `»» id` | string(uuid) | false | | | +| `»» instance_id` | string | false | | | +| `»» last_connected_at` | string(date-time) | false | | | +| `»» latency` | object | false | | DERPLatency is mapped by region name (e.g. "New York City", "Seattle"). | +| `»»» [any property]` | `codersdk.DERPRegion` | false | | | +| `»»»» latency_ms` | number | false | | | +| `»»»» preferred` | boolean | false | | | +| `»» name` | string | false | | | +| `»» operating_system` | string | false | | | +| `»» resource_id` | string(uuid) | false | | | +| `»» startup_script` | string | false | | | +| `»» status` | string | false | | | +| `»» troubleshooting_url` | string | false | | | +| `»» updated_at` | string(date-time) | false | | | +| `»» version` | string | false | | | +| `» created_at` | string(date-time) | false | | | +| `» daily_cost` | integer | false | | | +| `» hide` | boolean | false | | | +| `» icon` | string | false | | | +| `» id` | string(uuid) | false | | | +| `» job_id` | string(uuid) | false | | | +| `» metadata` | array | false | | | +| `»» key` | string | false | | | +| `»» sensitive` | boolean | false | | | +| `»» value` | string | false | | | +| `» name` | string | false | | | +| `» type` | string | false | | | +| `» workspace_transition` | string | false | | | + +#### Enumerated Values + +| Property | Value | +| ---------------------- | --------------- | +| `sharing_level` | `owner` | +| `sharing_level` | `authenticated` | +| `sharing_level` | `public` | +| `status` | `connecting` | +| `status` | `connected` | +| `status` | `disconnected` | +| `status` | `timeout` | +| `workspace_transition` | `start` | +| `workspace_transition` | `stop` | +| `workspace_transition` | `delete` | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Get schema by template version + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/schema \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /templateversions/{templateversion}/schema` + +### Parameters + +| Name | In | Type | Required | Description | +| ----------------- | ---- | ------------ | -------- | ------------------- | +| `templateversion` | path | string(uuid) | true | Template version ID | + +### Example responses + +> 200 Response + +```json +[ + { + "allow_override_destination": true, + "allow_override_source": true, + "created_at": "2019-08-24T14:15:22Z", + "default_destination_scheme": "none", + "default_refresh": "string", + "default_source_scheme": "none", + "default_source_value": "string", + "description": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f", + "name": "string", + "redisplay_value": true, + "validation_condition": "string", + "validation_contains": ["string"], + "validation_error": "string", + "validation_type_system": "string", + "validation_value_type": "string" + } +] +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ----------------------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | array of [codersdk.ParameterSchema](schemas.md#codersdkparameterschema) | + +

Response Schema

+ +Status Code **200** + +| Name | Type | Required | Restrictions | Description | +| ------------------------------ | ----------------- | -------- | ------------ | -------------------------------------------------------------------------------------------------------------------------- | +| `[array item]` | array | false | | | +| `» allow_override_destination` | boolean | false | | | +| `» allow_override_source` | boolean | false | | | +| `» created_at` | string(date-time) | false | | | +| `» default_destination_scheme` | string | false | | | +| `» default_refresh` | string | false | | | +| `» default_source_scheme` | string | false | | | +| `» default_source_value` | string | false | | | +| `» description` | string | false | | | +| `» id` | string(uuid) | false | | | +| `» job_id` | string(uuid) | false | | | +| `» name` | string | false | | | +| `» redisplay_value` | boolean | false | | | +| `» validation_condition` | string | false | | | +| `» validation_contains` | array | false | | This is a special array of items provided if the validation condition
explicitly states the value must be one of a set. | +| `» validation_error` | string | false | | | +| `» validation_type_system` | string | false | | | +| `» validation_value_type` | string | false | | | + +#### Enumerated Values + +| Property | Value | +| ---------------------------- | ---------------------- | +| `default_destination_scheme` | `none` | +| `default_destination_scheme` | `environment_variable` | +| `default_destination_scheme` | `provisioner_variable` | +| `default_source_scheme` | `none` | +| `default_source_scheme` | `data` | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. From 5c96bd523d166951747615a9d0cc3a88151417e2 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Wed, 4 Jan 2023 16:29:07 +0100 Subject: [PATCH 21/36] Fix --- coderd/apidoc/docs.go | 28 ++++++------- coderd/apidoc/swagger.json | 28 ++++++------- coderd/templateversions.go | 28 ++++++------- docs/api/templates.md | 84 +++++++++++++++++++------------------- 4 files changed, 84 insertions(+), 84 deletions(-) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 2429df3b8232a..b65d9e7da6b66 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -1300,7 +1300,7 @@ const docTemplate = `{ } } }, - "/templateversions/{id}": { + "/templateversions/{templateversion}": { "get": { "security": [ { @@ -1320,7 +1320,7 @@ const docTemplate = `{ "type": "string", "format": "uuid", "description": "Template version ID", - "name": "id", + "name": "templateversion", "in": "path", "required": true } @@ -1335,7 +1335,7 @@ const docTemplate = `{ } } }, - "/templateversions/{id}/cancel": { + "/templateversions/{templateversion}/cancel": { "patch": { "security": [ { @@ -1355,7 +1355,7 @@ const docTemplate = `{ "type": "string", "format": "uuid", "description": "Template version ID", - "name": "id", + "name": "templateversion", "in": "path", "required": true } @@ -1370,7 +1370,7 @@ const docTemplate = `{ } } }, - "/templateversions/{id}/dry-run": { + "/templateversions/{templateversion}/dry-run": { "post": { "security": [ { @@ -1393,7 +1393,7 @@ const docTemplate = `{ "type": "string", "format": "uuid", "description": "Template version ID", - "name": "id", + "name": "templateversion", "in": "path", "required": true }, @@ -1417,7 +1417,7 @@ const docTemplate = `{ } } }, - "/templateversions/{templateversionid}/dry-run/{jobid}": { + "/templateversions/{templateversion}/dry-run/{jobid}": { "get": { "security": [ { @@ -1440,7 +1440,7 @@ const docTemplate = `{ "type": "string", "format": "uuid", "description": "Template version ID", - "name": "templateversionid", + "name": "templateversion", "in": "path", "required": true }, @@ -1463,7 +1463,7 @@ const docTemplate = `{ } } }, - "/templateversions/{templateversionid}/dry-run/{jobid}/cancel": { + "/templateversions/{templateversion}/dry-run/{jobid}/cancel": { "patch": { "security": [ { @@ -1483,7 +1483,7 @@ const docTemplate = `{ "type": "string", "format": "uuid", "description": "Template version ID", - "name": "id", + "name": "templateversion", "in": "path", "required": true } @@ -1498,7 +1498,7 @@ const docTemplate = `{ } } }, - "/templateversions/{templateversionid}/dry-run/{jobid}/logs": { + "/templateversions/{templateversion}/dry-run/{jobid}/logs": { "get": { "security": [ { @@ -1518,7 +1518,7 @@ const docTemplate = `{ "type": "string", "format": "uuid", "description": "Template version ID", - "name": "templateversionid", + "name": "templateversion", "in": "path", "required": true }, @@ -1562,7 +1562,7 @@ const docTemplate = `{ } } }, - "/templateversions/{templateversionid}/dry-run/{jobid}/resources": { + "/templateversions/{templateversion}/dry-run/{jobid}/resources": { "get": { "security": [ { @@ -1582,7 +1582,7 @@ const docTemplate = `{ "type": "string", "format": "uuid", "description": "Template version ID", - "name": "templateversionid", + "name": "templateversion", "in": "path", "required": true }, diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index d600ce601784a..e92fef8adfbd0 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -1136,7 +1136,7 @@ } } }, - "/templateversions/{id}": { + "/templateversions/{templateversion}": { "get": { "security": [ { @@ -1152,7 +1152,7 @@ "type": "string", "format": "uuid", "description": "Template version ID", - "name": "id", + "name": "templateversion", "in": "path", "required": true } @@ -1167,7 +1167,7 @@ } } }, - "/templateversions/{id}/cancel": { + "/templateversions/{templateversion}/cancel": { "patch": { "security": [ { @@ -1183,7 +1183,7 @@ "type": "string", "format": "uuid", "description": "Template version ID", - "name": "id", + "name": "templateversion", "in": "path", "required": true } @@ -1198,7 +1198,7 @@ } } }, - "/templateversions/{id}/dry-run": { + "/templateversions/{templateversion}/dry-run": { "post": { "security": [ { @@ -1215,7 +1215,7 @@ "type": "string", "format": "uuid", "description": "Template version ID", - "name": "id", + "name": "templateversion", "in": "path", "required": true }, @@ -1239,7 +1239,7 @@ } } }, - "/templateversions/{templateversionid}/dry-run/{jobid}": { + "/templateversions/{templateversion}/dry-run/{jobid}": { "get": { "security": [ { @@ -1256,7 +1256,7 @@ "type": "string", "format": "uuid", "description": "Template version ID", - "name": "templateversionid", + "name": "templateversion", "in": "path", "required": true }, @@ -1279,7 +1279,7 @@ } } }, - "/templateversions/{templateversionid}/dry-run/{jobid}/cancel": { + "/templateversions/{templateversion}/dry-run/{jobid}/cancel": { "patch": { "security": [ { @@ -1295,7 +1295,7 @@ "type": "string", "format": "uuid", "description": "Template version ID", - "name": "id", + "name": "templateversion", "in": "path", "required": true } @@ -1310,7 +1310,7 @@ } } }, - "/templateversions/{templateversionid}/dry-run/{jobid}/logs": { + "/templateversions/{templateversion}/dry-run/{jobid}/logs": { "get": { "security": [ { @@ -1326,7 +1326,7 @@ "type": "string", "format": "uuid", "description": "Template version ID", - "name": "templateversionid", + "name": "templateversion", "in": "path", "required": true }, @@ -1370,7 +1370,7 @@ } } }, - "/templateversions/{templateversionid}/dry-run/{jobid}/resources": { + "/templateversions/{templateversion}/dry-run/{jobid}/resources": { "get": { "security": [ { @@ -1386,7 +1386,7 @@ "type": "string", "format": "uuid", "description": "Template version ID", - "name": "templateversionid", + "name": "templateversion", "in": "path", "required": true }, diff --git a/coderd/templateversions.go b/coderd/templateversions.go index e606d170a6601..46c0973cbb47a 100644 --- a/coderd/templateversions.go +++ b/coderd/templateversions.go @@ -33,9 +33,9 @@ import ( // @Security CoderSessionToken // @Produce json // @Tags Templates -// @Param id path string true "Template version ID" format(uuid) +// @Param templateversion path string true "Template version ID" format(uuid) // @Success 200 {object} codersdk.TemplateVersion -// @Router /templateversions/{id} [get] +// @Router /templateversions/{templateversion} [get] func (api *API) templateVersion(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() var ( @@ -74,9 +74,9 @@ func (api *API) templateVersion(rw http.ResponseWriter, r *http.Request) { // @Security CoderSessionToken // @Produce json // @Tags Templates -// @Param id path string true "Template version ID" format(uuid) +// @Param templateversion path string true "Template version ID" format(uuid) // @Success 200 {object} codersdk.Response -// @Router /templateversions/{id}/cancel [patch] +// @Router /templateversions/{templateversion}/cancel [patch] func (api *API) patchCancelTemplateVersion(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() var ( @@ -251,10 +251,10 @@ func (api *API) templateVersionParameters(rw http.ResponseWriter, r *http.Reques // @Accept json // @Produce json // @Tags Templates -// @Param id path string true "Template version ID" format(uuid) +// @Param templateversion path string true "Template version ID" format(uuid) // @Param request body codersdk.CreateTemplateVersionDryRunRequest true "Dry-run request" // @Success 201 {object} codersdk.ProvisionerJob -// @Router /templateversions/{id}/dry-run [post] +// @Router /templateversions/{templateversion}/dry-run [post] func (api *API) postTemplateVersionDryRun(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() var ( @@ -356,10 +356,10 @@ func (api *API) postTemplateVersionDryRun(rw http.ResponseWriter, r *http.Reques // @Accept json // @Produce json // @Tags Templates -// @Param templateversionid path string true "Template version ID" format(uuid) +// @Param templateversion path string true "Template version ID" format(uuid) // @Param jobid path string true "Job ID" format(uuid) // @Success 200 {object} codersdk.ProvisionerJob -// @Router /templateversions/{templateversionid}/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) @@ -375,10 +375,10 @@ func (api *API) templateVersionDryRun(rw http.ResponseWriter, r *http.Request) { // @Security CoderSessionToken // @Produce json // @Tags Templates -// @Param templateversionid path string true "Template version ID" format(uuid) +// @Param templateversion path string true "Template version ID" format(uuid) // @Param jobid path string true "Job ID" format(uuid) // @Success 200 {array} codersdk.WorkspaceResource -// @Router /templateversions/{templateversionid}/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 { @@ -393,13 +393,13 @@ func (api *API) templateVersionDryRunResources(rw http.ResponseWriter, r *http.R // @Security CoderSessionToken // @Produce json // @Tags Templates -// @Param templateversionid path string true "Template version ID" format(uuid) +// @Param templateversion path string true "Template version 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/{templateversionid}/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 +414,9 @@ func (api *API) templateVersionDryRunLogs(rw http.ResponseWriter, r *http.Reques // @Security CoderSessionToken // @Produce json // @Tags Templates -// @Param id path string true "Template version ID" format(uuid) +// @Param templateversion path string true "Template version ID" format(uuid) // @Success 200 {object} codersdk.Response -// @Router /templateversions/{templateversionid}/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) diff --git a/docs/api/templates.md b/docs/api/templates.md index e7c586d459b90..73c616e652e30 100644 --- a/docs/api/templates.md +++ b/docs/api/templates.md @@ -1074,18 +1074,18 @@ To perform this operation, you must be authenticated by means of one of the foll ```shell # Example request using curl -curl -X GET http://coder-server:8080/api/v2/templateversions/{id} \ +curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion} \ -H 'Accept: application/json' \ -H 'Coder-Session-Token: API_KEY' ``` -`GET /templateversions/{id}` +`GET /templateversions/{templateversion}` ### Parameters -| Name | In | Type | Required | Description | -| ---- | ---- | ------------ | -------- | ------------------- | -| `id` | path | string(uuid) | true | Template version ID | +| Name | In | Type | Required | Description | +| ----------------- | ---- | ------------ | -------- | ------------------- | +| `templateversion` | path | string(uuid) | true | Template version ID | ### Example responses @@ -1148,18 +1148,18 @@ To perform this operation, you must be authenticated by means of one of the foll ```shell # Example request using curl -curl -X PATCH http://coder-server:8080/api/v2/templateversions/{id}/cancel \ +curl -X PATCH http://coder-server:8080/api/v2/templateversions/{templateversion}/cancel \ -H 'Accept: application/json' \ -H 'Coder-Session-Token: API_KEY' ``` -`PATCH /templateversions/{id}/cancel` +`PATCH /templateversions/{templateversion}/cancel` ### Parameters -| Name | In | Type | Required | Description | -| ---- | ---- | ------------ | -------- | ------------------- | -| `id` | path | string(uuid) | true | Template version ID | +| Name | In | Type | Required | Description | +| ----------------- | ---- | ------------ | -------- | ------------------- | +| `templateversion` | path | string(uuid) | true | Template version ID | ### Example responses @@ -1192,13 +1192,13 @@ To perform this operation, you must be authenticated by means of one of the foll ```shell # Example request using curl -curl -X POST http://coder-server:8080/api/v2/templateversions/{id}/dry-run \ +curl -X POST http://coder-server:8080/api/v2/templateversions/{templateversion}/dry-run \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Coder-Session-Token: API_KEY' ``` -`POST /templateversions/{id}/dry-run` +`POST /templateversions/{templateversion}/dry-run` > Body parameter @@ -1219,10 +1219,10 @@ curl -X POST http://coder-server:8080/api/v2/templateversions/{id}/dry-run \ ### Parameters -| Name | In | Type | Required | Description | -| ------ | ---- | ---------------------------------------------------------------------------------------------------- | -------- | ------------------- | -| `id` | path | string(uuid) | true | Template version ID | -| `body` | body | [codersdk.CreateTemplateVersionDryRunRequest](schemas.md#codersdkcreatetemplateversiondryrunrequest) | true | Dry-run request | +| Name | In | Type | Required | Description | +| ----------------- | ---- | ---------------------------------------------------------------------------------------------------- | -------- | ------------------- | +| `templateversion` | path | string(uuid) | true | Template version ID | +| `body` | body | [codersdk.CreateTemplateVersionDryRunRequest](schemas.md#codersdkcreatetemplateversiondryrunrequest) | true | Dry-run request | ### Example responses @@ -1260,19 +1260,19 @@ To perform this operation, you must be authenticated by means of one of the foll ```shell # Example request using curl -curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversionid}/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/{templateversionid}/dry-run/{jobid}` +`GET /templateversions/{templateversion}/dry-run/{jobid}` ### Parameters -| Name | In | Type | Required | Description | -| ------------------- | ---- | ------------ | -------- | ------------------- | -| `templateversionid` | path | string(uuid) | true | Template version ID | -| `jobid` | path | string(uuid) | true | Job ID | +| Name | In | Type | Required | Description | +| ----------------- | ---- | ------------ | -------- | ------------------- | +| `templateversion` | path | string(uuid) | true | Template version ID | +| `jobid` | path | string(uuid) | true | Job ID | ### Example responses @@ -1310,18 +1310,18 @@ To perform this operation, you must be authenticated by means of one of the foll ```shell # Example request using curl -curl -X PATCH http://coder-server:8080/api/v2/templateversions/{templateversionid}/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/{templateversionid}/dry-run/{jobid}/cancel` +`PATCH /templateversions/{templateversion}/dry-run/{jobid}/cancel` ### Parameters -| Name | In | Type | Required | Description | -| ---- | ---- | ------------ | -------- | ------------------- | -| `id` | path | string(uuid) | true | Template version ID | +| Name | In | Type | Required | Description | +| ----------------- | ---- | ------------ | -------- | ------------------- | +| `templateversion` | path | string(uuid) | true | Template version ID | ### Example responses @@ -1354,22 +1354,22 @@ To perform this operation, you must be authenticated by means of one of the foll ```shell # Example request using curl -curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversionid}/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/{templateversionid}/dry-run/{jobid}/logs` +`GET /templateversions/{templateversion}/dry-run/{jobid}/logs` ### Parameters -| Name | In | Type | Required | Description | -| ------------------- | ----- | ------------ | -------- | --------------------- | -| `templateversionid` | path | string(uuid) | true | Template version 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 | +| Name | In | Type | Required | Description | +| ----------------- | ----- | ------------ | -------- | --------------------- | +| `templateversion` | path | string(uuid) | true | Template version 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 | ### Example responses @@ -1426,19 +1426,19 @@ To perform this operation, you must be authenticated by means of one of the foll ```shell # Example request using curl -curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversionid}/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/{templateversionid}/dry-run/{jobid}/resources` +`GET /templateversions/{templateversion}/dry-run/{jobid}/resources` ### Parameters -| Name | In | Type | Required | Description | -| ------------------- | ---- | ------------ | -------- | ------------------- | -| `templateversionid` | path | string(uuid) | true | Template version ID | -| `jobid` | path | string(uuid) | true | Job ID | +| Name | In | Type | Required | Description | +| ----------------- | ---- | ------------ | -------- | ------------------- | +| `templateversion` | path | string(uuid) | true | Template version ID | +| `jobid` | path | string(uuid) | true | Job ID | ### Example responses From 4667f0761841c52d6daf864e9e1477009ab03b64 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Thu, 5 Jan 2023 14:14:56 +0100 Subject: [PATCH 22/36] WIP --- coderd/apidoc/docs.go | 242 +++++++++++++++++++++++++++++++++++++ coderd/apidoc/swagger.json | 207 +++++++++++++++++++++++++++++++ coderd/userauth.go | 21 ++++ coderd/users.go | 27 +++++ docs/api/authentication.md | 50 +++++++- docs/api/schemas.md | 84 +++++++++++++ docs/api/users.md | 164 +++++++++++++++++++++++++ docs/manifest.json | 8 ++ 8 files changed, 801 insertions(+), 2 deletions(-) create mode 100644 docs/api/users.md diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index b65d9e7da6b66..70949df688e74 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -1798,6 +1798,173 @@ const docTemplate = `{ } } }, + "/users/authmethods": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Get authentication methods", + "operationId": "get-authentication-methods", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.AuthMethods" + } + } + } + } + }, + "/users/first": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Check initial user created", + "operationId": "check-initial-user-created", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Create initial user", + "operationId": "create-initial-user", + "parameters": [ + { + "description": "First user request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateFirstUserRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.CreateFirstUserResponse" + } + } + } + } + }, + "/users/login": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Authentication" + ], + "summary": "Log in user", + "operationId": "log-in-user", + "parameters": [ + { + "description": "Login request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.LoginWithPasswordRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.LoginWithPasswordResponse" + } + } + } + } + }, + "/users/oauth2/github/callback": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "OAuth 2.0 GitHub Callback", + "operationId": "oauth2-github-callback", + "responses": { + "307": { + "description": "Temporary Redirect" + } + } + } + }, + "/users/oidc/callback": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "OpenID Connect Callback", + "operationId": "oidc-callback", + "responses": { + "307": { + "description": "Temporary Redirect" + } + } + } + }, "/users/{user}/workspace/{workspacename}": { "get": { "security": [ @@ -2995,6 +3162,20 @@ const docTemplate = `{ } } }, + "codersdk.AuthMethods": { + "type": "object", + "properties": { + "github": { + "type": "boolean" + }, + "oidc": { + "type": "boolean" + }, + "password": { + "type": "boolean" + } + } + }, "codersdk.AuthorizationCheck": { "description": "AuthorizationCheck is used to check if the currently authenticated user (or the specified user) can do a given action to a given set of objects.", "type": "object", @@ -3082,6 +3263,41 @@ const docTemplate = `{ } } }, + "codersdk.CreateFirstUserRequest": { + "type": "object", + "required": [ + "email", + "password", + "username" + ], + "properties": { + "email": { + "type": "string" + }, + "password": { + "type": "string" + }, + "trial": { + "type": "boolean" + }, + "username": { + "type": "string" + } + } + }, + "codersdk.CreateFirstUserResponse": { + "type": "object", + "properties": { + "organization_id": { + "type": "string", + "format": "uuid" + }, + "user_id": { + "type": "string", + "format": "uuid" + } + } + }, "codersdk.CreateOrganizationRequest": { "type": "object", "required": [ @@ -3708,6 +3924,32 @@ const docTemplate = `{ } } }, + "codersdk.LoginWithPasswordRequest": { + "type": "object", + "required": [ + "email", + "password" + ], + "properties": { + "email": { + "type": "string" + }, + "password": { + "type": "string" + } + } + }, + "codersdk.LoginWithPasswordResponse": { + "type": "object", + "required": [ + "session_token" + ], + "properties": { + "session_token": { + "type": "string" + } + } + }, "codersdk.OAuth2Config": { "type": "object", "properties": { diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index e92fef8adfbd0..380634bbc689e 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -1582,6 +1582,147 @@ } } }, + "/users/authmethods": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Get authentication methods", + "operationId": "get-authentication-methods", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.AuthMethods" + } + } + } + } + }, + "/users/first": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Check initial user created", + "operationId": "check-initial-user-created", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Create initial user", + "operationId": "create-initial-user", + "parameters": [ + { + "description": "First user request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateFirstUserRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.CreateFirstUserResponse" + } + } + } + } + }, + "/users/login": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Authentication"], + "summary": "Log in user", + "operationId": "log-in-user", + "parameters": [ + { + "description": "Login request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.LoginWithPasswordRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.LoginWithPasswordResponse" + } + } + } + } + }, + "/users/oauth2/github/callback": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "OAuth 2.0 GitHub Callback", + "operationId": "oauth2-github-callback", + "responses": { + "307": { + "description": "Temporary Redirect" + } + } + } + }, + "/users/oidc/callback": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "OpenID Connect Callback", + "operationId": "oidc-callback", + "responses": { + "307": { + "description": "Temporary Redirect" + } + } + } + }, "/users/{user}/workspace/{workspacename}": { "get": { "security": [ @@ -2657,6 +2798,20 @@ } } }, + "codersdk.AuthMethods": { + "type": "object", + "properties": { + "github": { + "type": "boolean" + }, + "oidc": { + "type": "boolean" + }, + "password": { + "type": "boolean" + } + } + }, "codersdk.AuthorizationCheck": { "description": "AuthorizationCheck is used to check if the currently authenticated user (or the specified user) can do a given action to a given set of objects.", "type": "object", @@ -2736,6 +2891,37 @@ } } }, + "codersdk.CreateFirstUserRequest": { + "type": "object", + "required": ["email", "password", "username"], + "properties": { + "email": { + "type": "string" + }, + "password": { + "type": "string" + }, + "trial": { + "type": "boolean" + }, + "username": { + "type": "string" + } + } + }, + "codersdk.CreateFirstUserResponse": { + "type": "object", + "properties": { + "organization_id": { + "type": "string", + "format": "uuid" + }, + "user_id": { + "type": "string", + "format": "uuid" + } + } + }, "codersdk.CreateOrganizationRequest": { "type": "object", "required": ["name"], @@ -3335,6 +3521,27 @@ } } }, + "codersdk.LoginWithPasswordRequest": { + "type": "object", + "required": ["email", "password"], + "properties": { + "email": { + "type": "string" + }, + "password": { + "type": "string" + } + } + }, + "codersdk.LoginWithPasswordResponse": { + "type": "object", + "required": ["session_token"], + "properties": { + "session_token": { + "type": "string" + } + } + }, "codersdk.OAuth2Config": { "type": "object", "properties": { diff --git a/coderd/userauth.go b/coderd/userauth.go index 1197aa8d2cea6..dfd72e7c9a9c0 100644 --- a/coderd/userauth.go +++ b/coderd/userauth.go @@ -43,6 +43,13 @@ type GithubOAuth2Config struct { AllowTeams []GithubOAuth2Team } +// @Summary Get authentication methods +// @ID get-authentication-methods +// @Security CoderSessionToken +// @Produce json +// @Tags Users +// @Success 200 {object} codersdk.AuthMethods +// @Router /users/authmethods [get] func (api *API) userAuthMethods(rw http.ResponseWriter, r *http.Request) { httpapi.Write(r.Context(), rw, http.StatusOK, codersdk.AuthMethods{ Password: true, @@ -51,6 +58,13 @@ func (api *API) userAuthMethods(rw http.ResponseWriter, r *http.Request) { }) } +// @Summary OAuth 2.0 GitHub Callback +// @ID oauth2-github-callback +// @Security CoderSessionToken +// @Produce json +// @Tags Users +// @Success 307 +// @Router /users/oauth2/github/callback [get] func (api *API) userOAuth2Github(rw http.ResponseWriter, r *http.Request) { var ( ctx = r.Context() @@ -200,6 +214,13 @@ type OIDCConfig struct { IgnoreEmailVerified bool } +// @Summary OpenID Connect Callback +// @ID oidc-callback +// @Security CoderSessionToken +// @Produce json +// @Tags Users +// @Success 307 +// @Router /users/oidc/callback [get] func (api *API) userOIDC(rw http.ResponseWriter, r *http.Request) { var ( ctx = r.Context() diff --git a/coderd/users.go b/coderd/users.go index ea47cd66d4553..e307f28a750ee 100644 --- a/coderd/users.go +++ b/coderd/users.go @@ -30,6 +30,14 @@ import ( "github.com/coder/coder/examples" ) +// @Summary Check initial user created +// @ID check-initial-user-created +// @Security CoderSessionToken +// @Produce json +// @Tags Users +// @Success 200 {object} codersdk.Response +// @Router /users/first [get] +// // Returns whether the initial user has been created or not. func (api *API) firstUser(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() @@ -54,6 +62,16 @@ func (api *API) firstUser(rw http.ResponseWriter, r *http.Request) { }) } +// @Summary Create initial user +// @ID create-initial-user +// @Security CoderSessionToken +// @Accept json +// @Produce json +// @Tags Users +// @Param request body codersdk.CreateFirstUserRequest true "First user request" +// @Success 201 {object} codersdk.CreateFirstUserResponse +// @Router /users/first [post] +// // Creates the initial user for a Coder deployment. func (api *API) postFirstUser(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() @@ -908,6 +926,15 @@ func (api *API) organizationByUserAndName(rw http.ResponseWriter, r *http.Reques httpapi.Write(ctx, rw, http.StatusOK, convertOrganization(organization)) } +// @Summary Log in user +// @ID log-in-user +// @Security CoderSessionToken +// @Produce json +// @Tags Authentication +// @Param request body codersdk.LoginWithPasswordRequest true "Login request" +// @Success 201 {object} codersdk.LoginWithPasswordResponse +// @Router /users/login [post] +// // Authenticates the user with an email and password. func (api *API) postLogin(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() diff --git a/docs/api/authentication.md b/docs/api/authentication.md index 8c3c209b1ae7c..b323a93c685e2 100644 --- a/docs/api/authentication.md +++ b/docs/api/authentication.md @@ -1,4 +1,50 @@ # Authentication -- API Key (CoderSessionToken) - - Parameter Name: **Coder-Session-Token**, in: header. +> This page is incomplete, stay tuned. + +## Log in user + +### Code samples + +```shell +# Example request using curl +curl -X POST http://coder-server:8080/api/v2/users/login \ + -H 'Content-Type: application/json' \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`POST /users/login` + +> Body parameter + +```json +{ + "email": "string", + "password": "string" +} +``` + +### Parameters + +| Name | In | Type | Required | Description | +| ------ | ---- | -------------------------------------------------------------------------------- | -------- | ------------- | +| `body` | body | [codersdk.LoginWithPasswordRequest](schemas.md#codersdkloginwithpasswordrequest) | true | Login request | + +### Example responses + +> 201 Response + +```json +{ + "session_token": "string" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------------ | ----------- | ---------------------------------------------------------------------------------- | +| 201 | [Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) | Created | [codersdk.LoginWithPasswordResponse](schemas.md#codersdkloginwithpasswordresponse) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. diff --git a/docs/api/schemas.md b/docs/api/schemas.md index 87cffd52a8d78..085628179616a 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -286,6 +286,24 @@ | `audit_logs` | array of [codersdk.AuditLog](#codersdkauditlog) | false | | | | `count` | integer | false | | | +## codersdk.AuthMethods + +```json +{ + "github": true, + "oidc": true, + "password": true +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ---------- | ------- | -------- | ------------ | ----------- | +| `github` | boolean | false | | | +| `oidc` | boolean | false | | | +| `password` | boolean | false | | | + ## codersdk.AuthorizationCheck ```json @@ -421,6 +439,42 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in | `external_url` | string | false | | External URL references the current Coder version. For production builds, this will link directly to a release. For development builds, this will link to a commit. | | `version` | string | false | | Version returns the semantic version of the build. | +## codersdk.CreateFirstUserRequest + +```json +{ + "email": "string", + "password": "string", + "trial": true, + "username": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ---------- | ------- | -------- | ------------ | ----------- | +| `email` | string | true | | | +| `password` | string | true | | | +| `trial` | boolean | false | | | +| `username` | string | true | | | + +## codersdk.CreateFirstUserResponse + +```json +{ + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ----------------- | ------ | -------- | ------------ | ----------- | +| `organization_id` | string | false | | | +| `user_id` | string | false | | | + ## codersdk.CreateOrganizationRequest ```json @@ -2021,6 +2075,36 @@ CreateParameterRequest is a structure used to create a new parameter value for a | `threshold` | integer | false | | Threshold specifies the number of consecutive failed health checks before returning "unhealthy". | | `url` | string | false | | URL specifies the endpoint to check for the app health. | +## codersdk.LoginWithPasswordRequest + +```json +{ + "email": "string", + "password": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ---------- | ------ | -------- | ------------ | ----------- | +| `email` | string | true | | | +| `password` | string | true | | | + +## codersdk.LoginWithPasswordResponse + +```json +{ + "session_token": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| --------------- | ------ | -------- | ------------ | ----------- | +| `session_token` | string | true | | | + ## codersdk.OAuth2Config ```json diff --git a/docs/api/users.md b/docs/api/users.md new file mode 100644 index 0000000000000..a8609c9157560 --- /dev/null +++ b/docs/api/users.md @@ -0,0 +1,164 @@ +# Users + +> This page is incomplete, stay tuned. + +## Get authentication methods + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/users/authmethods \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /users/authmethods` + +### Example responses + +> 200 Response + +```json +{ + "github": true, + "oidc": true, + "password": true +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ------------------------------------------------------ | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.AuthMethods](schemas.md#codersdkauthmethods) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Check initial user created + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/users/first \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /users/first` + +### Example responses + +> 200 Response + +```json +{ + "detail": "string", + "message": "string", + "validations": [ + { + "detail": "string", + "field": "string" + } + ] +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ------------------------------------------------ | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.Response](schemas.md#codersdkresponse) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## Create initial user + +### Code samples + +```shell +# Example request using curl +curl -X POST http://coder-server:8080/api/v2/users/first \ + -H 'Content-Type: application/json' \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`POST /users/first` + +> Body parameter + +```json +{ + "email": "string", + "password": "string", + "trial": true, + "username": "string" +} +``` + +### Parameters + +| Name | In | Type | Required | Description | +| ------ | ---- | ---------------------------------------------------------------------------- | -------- | ------------------ | +| `body` | body | [codersdk.CreateFirstUserRequest](schemas.md#codersdkcreatefirstuserrequest) | true | First user request | + +### Example responses + +> 201 Response + +```json +{ + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------------ | ----------- | ------------------------------------------------------------------------------ | +| 201 | [Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) | Created | [codersdk.CreateFirstUserResponse](schemas.md#codersdkcreatefirstuserresponse) | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## OAuth 2.0 GitHub Callback + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/users/oauth2/github/callback \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /users/oauth2/github/callback` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ----------------------------------------------------------------------- | ------------------ | ------ | +| 307 | [Temporary Redirect](https://tools.ietf.org/html/rfc7231#section-6.4.7) | Temporary Redirect | | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. + +## OpenID Connect Callback + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/users/oidc/callback \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /users/oidc/callback` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ----------------------------------------------------------------------- | ------------------ | ------ | +| 307 | [Temporary Redirect](https://tools.ietf.org/html/rfc7231#section-6.4.7) | Temporary Redirect | | + +To perform this operation, you must be authenticated by means of one of the following methods: **CoderSessionToken**. diff --git a/docs/manifest.json b/docs/manifest.json index 603771bedcb0b..22546066c1dee 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -369,6 +369,14 @@ "title": "Parameters", "path": "./api/parameters.md" }, + { + "title": "Users", + "path": "./api/users.md" + }, + { + "title": "Authentication", + "path": "./api/authentication.md" + }, { "title": "Agents", "path": "./api/agents.md" From 5405c0cc861056112a861e9bd02116454197cb00 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Mon, 9 Jan 2023 10:27:48 +0100 Subject: [PATCH 23/36] WIP --- coderd/apidoc/docs.go | 9 ++++++--- coderd/apidoc/swagger.json | 9 ++++++--- codersdk/templates.go | 6 +++--- docs/api/schemas.md | 6 +++--- docs/api/templates.md | 36 ++++++++++++++++++------------------ 5 files changed, 36 insertions(+), 30 deletions(-) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 75f0fc8d2a3dd..9981be1f869ff 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -4192,7 +4192,8 @@ const docTemplate = `{ "type": "integer" }, "active_version_id": { - "type": "string" + "type": "string", + "format": "uuid" }, "allow_user_cancel_workspace_jobs": { "type": "boolean" @@ -4273,7 +4274,8 @@ const docTemplate = `{ "type": "string" }, "id": { - "type": "string" + "type": "string", + "format": "uuid" }, "markdown": { "type": "string" @@ -4363,7 +4365,8 @@ const docTemplate = `{ ], "properties": { "id": { - "type": "string" + "type": "string", + "format": "uuid" } } }, diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 6c299f672d80a..1e5e21d62b630 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -3788,7 +3788,8 @@ "type": "integer" }, "active_version_id": { - "type": "string" + "type": "string", + "format": "uuid" }, "allow_user_cancel_workspace_jobs": { "type": "boolean" @@ -3869,7 +3870,8 @@ "type": "string" }, "id": { - "type": "string" + "type": "string", + "format": "uuid" }, "markdown": { "type": "string" @@ -3957,7 +3959,8 @@ "required": ["id"], "properties": { "id": { - "type": "string" + "type": "string", + "format": "uuid" } } }, diff --git a/codersdk/templates.go b/codersdk/templates.go index ee14775430005..2985f6e3aac15 100644 --- a/codersdk/templates.go +++ b/codersdk/templates.go @@ -21,7 +21,7 @@ type Template struct { Name string `json:"name"` DisplayName string `json:"display_name"` Provisioner ProvisionerType `json:"provisioner"` - ActiveVersionID uuid.UUID `json:"active_version_id"` + ActiveVersionID uuid.UUID `json:"active_version_id" format:"uuid"` WorkspaceOwnerCount uint32 `json:"workspace_owner_count"` // ActiveUserCount is set to -1 when loading. ActiveUserCount int `json:"active_user_count"` @@ -42,7 +42,7 @@ type TransitionStats struct { type TemplateBuildTimeStats map[WorkspaceTransition]TransitionStats type UpdateActiveTemplateVersion struct { - ID uuid.UUID `json:"id" validate:"required"` + ID uuid.UUID `json:"id" validate:"required" format:"uuid"` } type TemplateRole string @@ -83,7 +83,7 @@ type UpdateTemplateMeta struct { } type TemplateExample struct { - ID string `json:"id"` + ID string `json:"id" format:"uuid"` URL string `json:"url"` Name string `json:"name"` Description string `json:"description"` diff --git a/docs/api/schemas.md b/docs/api/schemas.md index 95c599564570e..d7c417a343460 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -2955,7 +2955,7 @@ Parameter represents a set value for the scope. ```json { "active_user_count": 0, - "active_version_id": "string", + "active_version_id": "eae64611-bd53-4a80-bb77-df1e432c0fbc", "allow_user_cancel_workspace_jobs": true, "build_time_stats": { "property1": { @@ -3051,7 +3051,7 @@ Parameter represents a set value for the scope. { "description": "string", "icon": "string", - "id": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "markdown": "string", "name": "string", "tags": ["string"], @@ -3198,7 +3198,7 @@ Parameter represents a set value for the scope. ```json { - "id": "string" + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08" } ``` diff --git a/docs/api/templates.md b/docs/api/templates.md index 6cbe43073fb25..81c4aa5024213 100644 --- a/docs/api/templates.md +++ b/docs/api/templates.md @@ -29,7 +29,7 @@ curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/templat [ { "active_user_count": 0, - "active_version_id": "string", + "active_version_id": "eae64611-bd53-4a80-bb77-df1e432c0fbc", "allow_user_cancel_workspace_jobs": true, "build_time_stats": { "property1": { @@ -72,7 +72,7 @@ Status Code **200** | ------------------------------------ | --------------------------------- | -------- | ------------ | ------------------------------------------ | | `[array item]` | array | false | | | | `» active_user_count` | integer | false | | ActiveUserCount is set to -1 when loading. | -| `» active_version_id` | string | false | | | +| `» active_version_id` | string(uuid) | false | | | | `» allow_user_cancel_workspace_jobs` | boolean | false | | | | `» build_time_stats` | `codersdk.TemplateBuildTimeStats` | false | | | | `»» [any property]` | `codersdk.TransitionStats` | false | | | @@ -145,7 +145,7 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/templa ```json { "active_user_count": 0, - "active_version_id": "string", + "active_version_id": "eae64611-bd53-4a80-bb77-df1e432c0fbc", "allow_user_cancel_workspace_jobs": true, "build_time_stats": { "property1": { @@ -209,7 +209,7 @@ curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/templat { "description": "string", "icon": "string", - "id": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "markdown": "string", "name": "string", "tags": ["string"], @@ -228,16 +228,16 @@ curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/templat Status Code **200** -| Name | Type | Required | Restrictions | Description | -| --------------- | ------ | -------- | ------------ | ----------- | -| `[array item]` | array | false | | | -| `» description` | string | false | | | -| `» icon` | string | false | | | -| `» id` | string | false | | | -| `» markdown` | string | false | | | -| `» name` | string | false | | | -| `» tags` | array | false | | | -| `» url` | string | false | | | +| Name | Type | Required | Restrictions | Description | +| --------------- | ------------ | -------- | ------------ | ----------- | +| `[array item]` | array | false | | | +| `» description` | string | false | | | +| `» icon` | string | false | | | +| `» id` | string(uuid) | false | | | +| `» markdown` | string | false | | | +| `» name` | string | false | | | +| `» tags` | array | false | | | +| `» url` | string | false | | | To perform this operation, you must be authenticated. [Learn more](authentication.md). @@ -268,7 +268,7 @@ curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/templat ```json { "active_user_count": 0, - "active_version_id": "string", + "active_version_id": "eae64611-bd53-4a80-bb77-df1e432c0fbc", "allow_user_cancel_workspace_jobs": true, "build_time_stats": { "property1": { @@ -573,7 +573,7 @@ curl -X GET http://coder-server:8080/api/v2/templates/{id} \ ```json { "active_user_count": 0, - "active_version_id": "string", + "active_version_id": "eae64611-bd53-4a80-bb77-df1e432c0fbc", "allow_user_cancel_workspace_jobs": true, "build_time_stats": { "property1": { @@ -679,7 +679,7 @@ curl -X PATCH http://coder-server:8080/api/v2/templates/{id} \ ```json { "active_user_count": 0, - "active_version_id": "string", + "active_version_id": "eae64611-bd53-4a80-bb77-df1e432c0fbc", "allow_user_cancel_workspace_jobs": true, "build_time_stats": { "property1": { @@ -903,7 +903,7 @@ curl -X PATCH http://coder-server:8080/api/v2/templates/{id}/versions \ ```json { - "id": "string" + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08" } ``` From 0dc1d2ab216a4806c192c11ff536e09db28aeee6 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Mon, 9 Jan 2023 10:45:21 +0100 Subject: [PATCH 24/36] Users --- coderd/apidoc/docs.go | 150 ++++++++++++++++++++++++++++++++++++- coderd/apidoc/swagger.json | 135 ++++++++++++++++++++++++++++++++- coderd/templateversions.go | 3 + coderd/users.go | 21 ++++++ codersdk/users.go | 4 +- docs/api/audit.md | 2 +- docs/api/schemas.md | 61 ++++++++++++++- docs/api/templates.md | 25 ++++--- docs/api/users.md | 120 +++++++++++++++++++++++++++++ 9 files changed, 501 insertions(+), 20 deletions(-) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 05aca50e2d4d2..58eb9c2acc55c 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -1195,6 +1195,25 @@ const docTemplate = `{ "name": "id", "in": "path", "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "After ID", + "name": "after_id", + "in": "query" + }, + { + "type": "integer", + "description": "Page limit", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "description": "Page offset", + "name": "offset", + "in": "query" } ], "responses": { @@ -1798,6 +1817,95 @@ const docTemplate = `{ } } }, + "/users": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Get users", + "operationId": "get-users", + "parameters": [ + { + "type": "string", + "description": "Search query", + "name": "q", + "in": "query" + }, + { + "type": "string", + "format": "uuid", + "description": "After ID", + "name": "after_id", + "in": "query" + }, + { + "type": "integer", + "description": "Page limit", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "description": "Page offset", + "name": "offset", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.GetUsersResponse" + } + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Create new user", + "operationId": "create-new-user", + "parameters": [ + { + "description": "Create user request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateUserRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.User" + } + } + } + } + }, "/users/authmethods": { "get": { "security": [ @@ -3439,6 +3547,31 @@ const docTemplate = `{ } } }, + "codersdk.CreateUserRequest": { + "type": "object", + "required": [ + "email", + "organization_id", + "password", + "username" + ], + "properties": { + "email": { + "type": "string", + "format": "email" + }, + "organization_id": { + "type": "string", + "format": "uuid" + }, + "password": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, "codersdk.CreateWorkspaceBuildRequest": { "type": "object", "required": [ @@ -3858,6 +3991,20 @@ const docTemplate = `{ } } }, + "codersdk.GetUsersResponse": { + "type": "object", + "properties": { + "count": { + "type": "integer" + }, + "users": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.User" + } + } + } + }, "codersdk.GitAuthConfig": { "type": "object", "properties": { @@ -4691,7 +4838,8 @@ const docTemplate = `{ "format": "date-time" }, "email": { - "type": "string" + "type": "string", + "format": "email" }, "id": { "type": "string", diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 52fc33a6af492..064b1758280d7 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -1041,6 +1041,25 @@ "name": "id", "in": "path", "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "After ID", + "name": "after_id", + "in": "query" + }, + { + "type": "integer", + "description": "Page limit", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "description": "Page offset", + "name": "offset", + "in": "query" } ], "responses": { @@ -1582,6 +1601,85 @@ } } }, + "/users": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Get users", + "operationId": "get-users", + "parameters": [ + { + "type": "string", + "description": "Search query", + "name": "q", + "in": "query" + }, + { + "type": "string", + "format": "uuid", + "description": "After ID", + "name": "after_id", + "in": "query" + }, + { + "type": "integer", + "description": "Page limit", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "description": "Page offset", + "name": "offset", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.GetUsersResponse" + } + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Create new user", + "operationId": "create-new-user", + "parameters": [ + { + "description": "Create user request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateUserRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.User" + } + } + } + } + }, "/users/authmethods": { "get": { "security": [ @@ -3045,6 +3143,26 @@ } } }, + "codersdk.CreateUserRequest": { + "type": "object", + "required": ["email", "organization_id", "password", "username"], + "properties": { + "email": { + "type": "string", + "format": "email" + }, + "organization_id": { + "type": "string", + "format": "uuid" + }, + "password": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, "codersdk.CreateWorkspaceBuildRequest": { "type": "object", "required": ["transition"], @@ -3457,6 +3575,20 @@ } } }, + "codersdk.GetUsersResponse": { + "type": "object", + "properties": { + "count": { + "type": "integer" + }, + "users": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.User" + } + } + } + }, "codersdk.GitAuthConfig": { "type": "object", "properties": { @@ -4245,7 +4377,8 @@ "format": "date-time" }, "email": { - "type": "string" + "type": "string", + "format": "email" }, "id": { "type": "string", diff --git a/coderd/templateversions.go b/coderd/templateversions.go index 46c0973cbb47a..15ac9a502711b 100644 --- a/coderd/templateversions.go +++ b/coderd/templateversions.go @@ -541,6 +541,9 @@ func (api *API) fetchTemplateVersionDryRunJob(rw http.ResponseWriter, r *http.Re // @Produce json // @Tags Templates // @Param id 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] func (api *API) templateVersionsByTemplate(rw http.ResponseWriter, r *http.Request) { diff --git a/coderd/users.go b/coderd/users.go index 1a1ad8ea05449..7076cc119ae32 100644 --- a/coderd/users.go +++ b/coderd/users.go @@ -153,6 +153,17 @@ func (api *API) postFirstUser(rw http.ResponseWriter, r *http.Request) { }) } +// @Summary Get users +// @ID get-users +// @Security CoderSessionToken +// @Produce json +// @Tags Users +// @Param q query string false "Search query" +// @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 {object} codersdk.GetUsersResponse +// @Router /users [get] func (api *API) users(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() query := r.URL.Query().Get("q") @@ -232,6 +243,16 @@ func (api *API) users(rw http.ResponseWriter, r *http.Request) { } // Creates a new user. +// +// @Summary Create new user +// @ID create-new-user +// @Security CoderSessionToken +// @Accept json +// @Produce json +// @Tags Users +// @Param request body codersdk.CreateUserRequest true "Create user request" +// @Success 201 {object} codersdk.User +// @Router /users [post] func (api *API) postUser(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() auditor := *api.Auditor.Load() diff --git a/codersdk/users.go b/codersdk/users.go index 4b1f24afac933..b6f2926c09a0b 100644 --- a/codersdk/users.go +++ b/codersdk/users.go @@ -37,7 +37,7 @@ type UsersRequest struct { type User struct { ID uuid.UUID `json:"id" validate:"required" table:"id" format:"uuid"` Username string `json:"username" validate:"required" table:"username"` - Email string `json:"email" validate:"required" table:"email"` + Email string `json:"email" validate:"required" table:"email" format:"email"` CreatedAt time.Time `json:"created_at" validate:"required" table:"created at" format:"date-time"` LastSeenAt time.Time `json:"last_seen_at" format:"date-time"` @@ -66,7 +66,7 @@ type CreateFirstUserResponse struct { } type CreateUserRequest struct { - Email string `json:"email" validate:"required,email"` + Email string `json:"email" validate:"required,email" format:"email"` Username string `json:"username" validate:"required,username"` Password string `json:"password" validate:"required"` OrganizationID uuid.UUID `json:"organization_id" validate:"required" format:"uuid"` diff --git a/docs/api/audit.md b/docs/api/audit.md index edaeca1e0dfe8..4c94f8eb815a8 100644 --- a/docs/api/audit.md +++ b/docs/api/audit.md @@ -62,7 +62,7 @@ curl -X GET http://coder-server:8080/api/v2/audit?q=string \ "user": { "avatar_url": "http://example.com", "created_at": "2019-08-24T14:15:22Z", - "email": "string", + "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"], diff --git a/docs/api/schemas.md b/docs/api/schemas.md index a236dc23ce88e..7d7328e9cdcc9 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -183,7 +183,7 @@ "user": { "avatar_url": "http://example.com", "created_at": "2019-08-24T14:15:22Z", - "email": "string", + "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"], @@ -259,7 +259,7 @@ "user": { "avatar_url": "http://example.com", "created_at": "2019-08-24T14:15:22Z", - "email": "string", + "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"], @@ -623,6 +623,26 @@ CreateParameterRequest is a structure used to create a new parameter value for a | `resource_type` | `api_key` | | `resource_type` | `group` | +## codersdk.CreateUserRequest + +```json +{ + "email": "user@example.com", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "password": "string", + "username": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ----------------- | ------ | -------- | ------------ | ----------- | +| `email` | string | true | | | +| `organization_id` | string | true | | | +| `password` | string | true | | | +| `username` | string | true | | | + ## codersdk.CreateWorkspaceBuildRequest ```json @@ -2012,6 +2032,39 @@ CreateParameterRequest is a structure used to create a new parameter value for a | ------ | ------ | -------- | ------------ | ------------------------------------------------------------- | | `host` | string | false | | Host is the externally accessible URL for the Coder instance. | +## codersdk.GetUsersResponse + +```json +{ + "count": 0, + "users": [ + { + "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" + } + ] +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ------- | --------------------------------------- | -------- | ------------ | ----------- | +| `count` | integer | false | | | +| `users` | array of [codersdk.User](#codersdkuser) | false | | | + ## codersdk.GitAuthConfig ```json @@ -3163,7 +3216,7 @@ Parameter represents a set value for the scope. "created_by": { "avatar_url": "http://example.com", "created_at": "2019-08-24T14:15:22Z", - "email": "string", + "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"], @@ -3386,7 +3439,7 @@ Parameter represents a set value for the scope. { "avatar_url": "http://example.com", "created_at": "2019-08-24T14:15:22Z", - "email": "string", + "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"], diff --git a/docs/api/templates.md b/docs/api/templates.md index 81c4aa5024213..749836cc8789a 100644 --- a/docs/api/templates.md +++ b/docs/api/templates.md @@ -352,7 +352,7 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/templa "created_by": { "avatar_url": "http://example.com", "created_at": "2019-08-24T14:15:22Z", - "email": "string", + "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"], @@ -427,7 +427,7 @@ curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/templat "created_by": { "avatar_url": "http://example.com", "created_at": "2019-08-24T14:15:22Z", - "email": "string", + "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"], @@ -502,7 +502,7 @@ curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/templat "created_by": { "avatar_url": "http://example.com", "created_at": "2019-08-24T14:15:22Z", - "email": "string", + "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"], @@ -772,9 +772,12 @@ curl -X GET http://coder-server:8080/api/v2/templates/{id}/versions \ ### Parameters -| Name | In | Type | Required | Description | -| ---- | ---- | ------------ | -------- | ----------- | -| `id` | path | string(uuid) | true | Template ID | +| Name | In | Type | Required | Description | +| ---------- | ----- | ------------ | -------- | ----------- | +| `id` | 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 | ### Example responses @@ -787,7 +790,7 @@ curl -X GET http://coder-server:8080/api/v2/templates/{id}/versions \ "created_by": { "avatar_url": "http://example.com", "created_at": "2019-08-24T14:15:22Z", - "email": "string", + "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"], @@ -842,7 +845,7 @@ Status Code **200** | `» created_by` | `codersdk.User` | false | | | | `»» avatar_url` | string(uri) | false | | | | `»» created_at` | string(date-time) | true | | | -| `»» email` | string | true | | | +| `»» email` | string(email) | true | | | | `»» id` | string(uuid) | true | | | | `»» last_seen_at` | string(date-time) | false | | | | `»» organization_ids` | array | false | | | @@ -970,7 +973,7 @@ curl -X GET http://coder-server:8080/api/v2/templates/{id}/versions/{templatever "created_by": { "avatar_url": "http://example.com", "created_at": "2019-08-24T14:15:22Z", - "email": "string", + "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"], @@ -1025,7 +1028,7 @@ Status Code **200** | `» created_by` | `codersdk.User` | false | | | | `»» avatar_url` | string(uri) | false | | | | `»» created_at` | string(date-time) | true | | | -| `»» email` | string | true | | | +| `»» email` | string(email) | true | | | | `»» id` | string(uuid) | true | | | | `»» last_seen_at` | string(date-time) | false | | | | `»» organization_ids` | array | false | | | @@ -1097,7 +1100,7 @@ curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion} \ "created_by": { "avatar_url": "http://example.com", "created_at": "2019-08-24T14:15:22Z", - "email": "string", + "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"], diff --git a/docs/api/users.md b/docs/api/users.md index 14c4678cfa48d..30d2ec3eb2421 100644 --- a/docs/api/users.md +++ b/docs/api/users.md @@ -2,6 +2,126 @@ > This page is incomplete, stay tuned. +## Get users + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/users \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /users` + +### Parameters + +| Name | In | Type | Required | Description | +| ---------- | ----- | ------------ | -------- | ------------ | +| `q` | query | string | false | Search query | +| `after_id` | query | string(uuid) | false | After ID | +| `limit` | query | integer | false | Page limit | +| `offset` | query | integer | false | Page offset | + +### Example responses + +> 200 Response + +```json +{ + "count": 0, + "users": [ + { + "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" + } + ] +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ---------------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.GetUsersResponse](schemas.md#codersdkgetusersresponse) | + +To perform this operation, you must be authenticated. [Learn more](authentication.md). + +## Create new user + +### Code samples + +```shell +# Example request using curl +curl -X POST http://coder-server:8080/api/v2/users \ + -H 'Content-Type: application/json' \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`POST /users` + +> Body parameter + +```json +{ + "email": "user@example.com", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "password": "string", + "username": "string" +} +``` + +### Parameters + +| Name | In | Type | Required | Description | +| ------ | ---- | ------------------------------------------------------------------ | -------- | ------------------- | +| `body` | body | [codersdk.CreateUserRequest](schemas.md#codersdkcreateuserrequest) | true | Create user request | + +### Example responses + +> 201 Response + +```json +{ + "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" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------------ | ----------- | ---------------------------------------- | +| 201 | [Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) | Created | [codersdk.User](schemas.md#codersdkuser) | + +To perform this operation, you must be authenticated. [Learn more](authentication.md). + ## Get authentication methods ### Code samples From 928542560f56a60be96e263cb4dc48f873ba6ca0 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Mon, 9 Jan 2023 10:57:51 +0100 Subject: [PATCH 25/36] Logout --- coderd/apidoc/docs.go | 53 ++++++++++++++++++++++++++++++++++++++ coderd/apidoc/swagger.json | 45 ++++++++++++++++++++++++++++++++ coderd/roles.go | 12 +++++++-- coderd/users.go | 8 ++++++ docs/api/members.md | 46 +++++++++++++++++++++++++++++++++ docs/api/users.md | 38 +++++++++++++++++++++++++++ 6 files changed, 200 insertions(+), 2 deletions(-) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 58eb9c2acc55c..53961afea9561 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -2029,6 +2029,31 @@ const docTemplate = `{ } } }, + "/users/logout": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Log out user", + "operationId": "log-out-user", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, "/users/oauth2/github/callback": { "get": { "security": [ @@ -2073,6 +2098,34 @@ const docTemplate = `{ } } }, + "/users/roles": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Members" + ], + "summary": "Get site member roles", + "operationId": "get-site-member-roles", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.AssignableRoles" + } + } + } + } + } + }, "/users/{user}/workspace/{workspacename}": { "get": { "security": [ diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 064b1758280d7..60c66f9bf6d11 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -1785,6 +1785,27 @@ } } }, + "/users/logout": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Log out user", + "operationId": "log-out-user", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, "/users/oauth2/github/callback": { "get": { "security": [ @@ -1821,6 +1842,30 @@ } } }, + "/users/roles": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Members"], + "summary": "Get site member roles", + "operationId": "get-site-member-roles", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.AssignableRoles" + } + } + } + } + } + }, "/users/{user}/workspace/{workspacename}": { "get": { "security": [ diff --git a/coderd/roles.go b/coderd/roles.go index 9eb1518d9ec6e..29be9c4a49172 100644 --- a/coderd/roles.go +++ b/coderd/roles.go @@ -11,6 +11,14 @@ import ( ) // assignableSiteRoles returns all site wide roles that can be assigned. +// +// @Summary Get site member roles +// @ID get-site-member-roles +// @Security CoderSessionToken +// @Produce json +// @Tags Members +// @Success 200 {array} codersdk.AssignableRoles +// @Router /users/roles [get] func (api *API) assignableSiteRoles(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() actorRoles := httpmw.UserAuthorization(r) @@ -23,6 +31,8 @@ func (api *API) assignableSiteRoles(rw http.ResponseWriter, r *http.Request) { httpapi.Write(ctx, rw, http.StatusOK, assignableRoles(actorRoles.Roles, roles)) } +// assignableSiteRoles returns all org wide roles that can be assigned. +// // @Summary Get member roles by organization // @ID get-member-roles-by-organization // @Security CoderSessionToken @@ -31,8 +41,6 @@ func (api *API) assignableSiteRoles(rw http.ResponseWriter, r *http.Request) { // @Param organization path string true "Organization ID" format(uuid) // @Success 200 {array} codersdk.AssignableRoles // @Router /organizations/{organization}/members/roles [get] -// -// assignableSiteRoles returns all site wide roles that can be assigned. func (api *API) assignableOrgRoles(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() organization := httpmw.OrganizationParam(r) diff --git a/coderd/users.go b/coderd/users.go index 7076cc119ae32..69da8a0e53e14 100644 --- a/coderd/users.go +++ b/coderd/users.go @@ -970,6 +970,14 @@ func (api *API) postLogin(rw http.ResponseWriter, r *http.Request) { } // Clear the user's session cookie. +// +// @Summary Log out user +// @ID log-out-user +// @Security CoderSessionToken +// @Produce json +// @Tags Users +// @Success 200 {object} codersdk.Response +// @Router /users/logout [post] func (api *API) postLogout(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() // Get a blank token cookie. diff --git a/docs/api/members.md b/docs/api/members.md index 389c6dcdba0e9..4b6d47095de6b 100644 --- a/docs/api/members.md +++ b/docs/api/members.md @@ -110,3 +110,49 @@ curl -X PUT http://coder-server:8080/api/v2/organizations/{organization}/members | 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.OrganizationMember](schemas.md#codersdkorganizationmember) | To perform this operation, you must be authenticated. [Learn more](authentication.md). + +## Get site member roles + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/users/roles \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /users/roles` + +### Example responses + +> 200 Response + +```json +[ + { + "assignable": true, + "display_name": "string", + "name": "string" + } +] +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ----------------------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | array of [codersdk.AssignableRoles](schemas.md#codersdkassignableroles) | + +

Response Schema

+ +Status Code **200** + +| Name | Type | Required | Restrictions | Description | +| ---------------- | ------- | -------- | ------------ | ----------- | +| `[array item]` | array | false | | | +| `» assignable` | boolean | false | | | +| `» display_name` | string | false | | | +| `» name` | string | false | | | + +To perform this operation, you must be authenticated. [Learn more](authentication.md). diff --git a/docs/api/users.md b/docs/api/users.md index 30d2ec3eb2421..7674388c5deeb 100644 --- a/docs/api/users.md +++ b/docs/api/users.md @@ -243,6 +243,44 @@ curl -X POST http://coder-server:8080/api/v2/users/first \ To perform this operation, you must be authenticated. [Learn more](authentication.md). +## Log out user + +### Code samples + +```shell +# Example request using curl +curl -X POST http://coder-server:8080/api/v2/users/logout \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`POST /users/logout` + +### Example responses + +> 200 Response + +```json +{ + "detail": "string", + "message": "string", + "validations": [ + { + "detail": "string", + "field": "string" + } + ] +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ------------------------------------------------ | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.Response](schemas.md#codersdkresponse) | + +To perform this operation, you must be authenticated. [Learn more](authentication.md). + ## OAuth 2.0 GitHub Callback ### Code samples From 6979a7f483e1acf64cdddb5e3b540ca571adf82d Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Mon, 9 Jan 2023 11:08:17 +0100 Subject: [PATCH 26/36] User profile --- coderd/apidoc/docs.go | 88 +++++++++++++++++++++++++++++ coderd/apidoc/swagger.json | 78 ++++++++++++++++++++++++++ coderd/users.go | 26 +++++++++ docs/api/schemas.md | 14 +++++ docs/api/users.md | 110 +++++++++++++++++++++++++++++++++++++ 5 files changed, 316 insertions(+) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 53961afea9561..5a6c94007b821 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -2126,6 +2126,83 @@ const docTemplate = `{ } } }, + "/users/{user}": { + "delete": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Get user by name", + "operationId": "get-user-by-name", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.User" + } + } + } + } + }, + "/users/{user}/profile": { + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Update user profile", + "operationId": "update-user-profile", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "description": "Updated profile", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateUserProfileRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.User" + } + } + } + } + }, "/users/{user}/workspace/{workspacename}": { "get": { "security": [ @@ -4840,6 +4917,17 @@ const docTemplate = `{ } } }, + "codersdk.UpdateUserProfileRequest": { + "type": "object", + "required": [ + "username" + ], + "properties": { + "username": { + "type": "string" + } + } + }, "codersdk.UpdateWorkspaceAutostartRequest": { "type": "object", "properties": { diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 60c66f9bf6d11..585b1c8095442 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -1866,6 +1866,75 @@ } } }, + "/users/{user}": { + "delete": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Get user by name", + "operationId": "get-user-by-name", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.User" + } + } + } + } + }, + "/users/{user}/profile": { + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Update user profile", + "operationId": "update-user-profile", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "description": "Updated profile", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateUserProfileRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.User" + } + } + } + } + }, "/users/{user}/workspace/{workspacename}": { "get": { "security": [ @@ -4376,6 +4445,15 @@ } } }, + "codersdk.UpdateUserProfileRequest": { + "type": "object", + "required": ["username"], + "properties": { + "username": { + "type": "string" + } + } + }, "codersdk.UpdateWorkspaceAutostartRequest": { "type": "object", "properties": { diff --git a/coderd/users.go b/coderd/users.go index 69da8a0e53e14..07da139d26253 100644 --- a/coderd/users.go +++ b/coderd/users.go @@ -339,6 +339,14 @@ func (api *API) postUser(rw http.ResponseWriter, r *http.Request) { httpapi.Write(ctx, rw, http.StatusCreated, convertUser(user, []uuid.UUID{req.OrganizationID})) } +// @Summary Delete user +// @ID delete-user +// @Security CoderSessionToken +// @Produce json +// @Tags Users +// @Param user path string true "User ID, name, or me" +// @Success 200 {object} codersdk.User +// @Router /users/{user} [delete] func (api *API) deleteUser(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() auditor := *api.Auditor.Load() @@ -394,6 +402,15 @@ func (api *API) deleteUser(rw http.ResponseWriter, r *http.Request) { // Returns the parameterized user requested. All validation // is completed in the middleware for this route. +// +// @Summary Get user by name +// @ID get-user-by-name +// @Security CoderSessionToken +// @Produce json +// @Tags Users +// @Param user path string true "User ID, name, or me" +// @Success 200 {object} codersdk.User +// @Router /users/{user} [delete] func (api *API) userByName(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() user := httpmw.UserParam(r) @@ -415,6 +432,15 @@ func (api *API) userByName(rw http.ResponseWriter, r *http.Request) { httpapi.Write(ctx, rw, http.StatusOK, convertUser(user, organizationIDs)) } +// @Summary Update user profile +// @ID update-user-profile +// @Security CoderSessionToken +// @Produce json +// @Tags Users +// @Param user path string true "User ID, name, or me" +// @Param request body codersdk.UpdateUserProfileRequest true "Updated profile" +// @Success 200 {object} codersdk.User +// @Router /users/{user}/profile [put] func (api *API) putUserProfile(rw http.ResponseWriter, r *http.Request) { var ( ctx = r.Context() diff --git a/docs/api/schemas.md b/docs/api/schemas.md index 7d7328e9cdcc9..ce5ab4c256317 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -3377,6 +3377,20 @@ Parameter represents a set value for the scope. | ------- | --------------- | -------- | ------------ | ----------- | | `roles` | array of string | false | | | +## codersdk.UpdateUserProfileRequest + +```json +{ + "username": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ---------- | ------ | -------- | ------------ | ----------- | +| `username` | string | true | | | + ## codersdk.UpdateWorkspaceAutostartRequest ```json diff --git a/docs/api/users.md b/docs/api/users.md index 7674388c5deeb..c2b9ab9711f02 100644 --- a/docs/api/users.md +++ b/docs/api/users.md @@ -320,3 +320,113 @@ curl -X GET http://coder-server:8080/api/v2/users/oidc/callback \ | 307 | [Temporary Redirect](https://tools.ietf.org/html/rfc7231#section-6.4.7) | Temporary Redirect | | To perform this operation, you must be authenticated. [Learn more](authentication.md). + +## Get user by name + +### Code samples + +```shell +# Example request using curl +curl -X DELETE http://coder-server:8080/api/v2/users/{user} \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`DELETE /users/{user}` + +### Parameters + +| Name | In | Type | Required | Description | +| ------ | ---- | ------ | -------- | -------------------- | +| `user` | path | string | true | User ID, name, or me | + +### Example responses + +> 200 Response + +```json +{ + "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" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ---------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.User](schemas.md#codersdkuser) | + +To perform this operation, you must be authenticated. [Learn more](authentication.md). + +## Update user profile + +### Code samples + +```shell +# Example request using curl +curl -X PUT http://coder-server:8080/api/v2/users/{user}/profile \ + -H 'Content-Type: application/json' \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`PUT /users/{user}/profile` + +> Body parameter + +```json +{ + "username": "string" +} +``` + +### Parameters + +| Name | In | Type | Required | Description | +| ------ | ---- | -------------------------------------------------------------------------------- | -------- | -------------------- | +| `user` | path | string | true | User ID, name, or me | +| `body` | body | [codersdk.UpdateUserProfileRequest](schemas.md#codersdkupdateuserprofilerequest) | true | Updated profile | + +### Example responses + +> 200 Response + +```json +{ + "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" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ---------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.User](schemas.md#codersdkuser) | + +To perform this operation, you must be authenticated. [Learn more](authentication.md). From 62a26f91df36bbfb146037372ac2da629de7bd39 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Mon, 9 Jan 2023 11:28:47 +0100 Subject: [PATCH 27/36] Status suspend activate --- coderd/apidoc/docs.go | 68 +++++++++++++++++++++++++ coderd/apidoc/swagger.json | 60 ++++++++++++++++++++++ coderd/coderd.go | 4 +- coderd/users.go | 24 +++++++++ docs/api/users.md | 100 +++++++++++++++++++++++++++++++++++++ 5 files changed, 254 insertions(+), 2 deletions(-) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 5a6c94007b821..3760b4972eaeb 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -2203,6 +2203,74 @@ const docTemplate = `{ } } }, + "/users/{user}/status/activate": { + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Activate user account", + "operationId": "activate-user-account", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.User" + } + } + } + } + }, + "/users/{user}/status/suspend": { + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Suspend user account", + "operationId": "suspend-user-account", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.User" + } + } + } + } + }, "/users/{user}/workspace/{workspacename}": { "get": { "security": [ diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 585b1c8095442..85de35c654d58 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -1935,6 +1935,66 @@ } } }, + "/users/{user}/status/activate": { + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Activate user account", + "operationId": "activate-user-account", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.User" + } + } + } + } + }, + "/users/{user}/status/suspend": { + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Suspend user account", + "operationId": "suspend-user-account", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.User" + } + } + } + } + }, "/users/{user}/workspace/{workspacename}": { "get": { "security": [ diff --git a/coderd/coderd.go b/coderd/coderd.go index 37db9d44e448c..1c647c3bf28f8 100644 --- a/coderd/coderd.go +++ b/coderd/coderd.go @@ -462,8 +462,8 @@ func New(options *Options) *API { r.Get("/", api.userByName) r.Put("/profile", api.putUserProfile) r.Route("/status", func(r chi.Router) { - r.Put("/suspend", api.putUserStatus(database.UserStatusSuspended)) - r.Put("/activate", api.putUserStatus(database.UserStatusActive)) + r.Put("/suspend", api.putSuspendUserAccount()) + r.Put("/activate", api.putActivateUserAccount()) }) r.Route("/password", func(r chi.Router) { r.Put("/", api.putUserPassword) diff --git a/coderd/users.go b/coderd/users.go index 07da139d26253..510fad34aab70 100644 --- a/coderd/users.go +++ b/coderd/users.go @@ -521,6 +521,30 @@ func (api *API) putUserProfile(rw http.ResponseWriter, r *http.Request) { httpapi.Write(ctx, rw, http.StatusOK, convertUser(updatedUserProfile, organizationIDs)) } +// @Summary Suspend user account +// @ID suspend-user-account +// @Security CoderSessionToken +// @Produce json +// @Tags Users +// @Param user path string true "User ID, name, or me" +// @Success 200 {object} codersdk.User +// @Router /users/{user}/status/suspend [put] +func (api *API) putSuspendUserAccount() func(rw http.ResponseWriter, r *http.Request) { + return api.putUserStatus(database.UserStatusSuspended) +} + +// @Summary Activate user account +// @ID activate-user-account +// @Security CoderSessionToken +// @Produce json +// @Tags Users +// @Param user path string true "User ID, name, or me" +// @Success 200 {object} codersdk.User +// @Router /users/{user}/status/activate [put] +func (api *API) putActivateUserAccount() func(rw http.ResponseWriter, r *http.Request) { + return api.putUserStatus(database.UserStatusSuspended) +} + func (api *API) putUserStatus(status database.UserStatus) func(rw http.ResponseWriter, r *http.Request) { return func(rw http.ResponseWriter, r *http.Request) { var ( diff --git a/docs/api/users.md b/docs/api/users.md index c2b9ab9711f02..2c07230967b20 100644 --- a/docs/api/users.md +++ b/docs/api/users.md @@ -430,3 +430,103 @@ curl -X PUT http://coder-server:8080/api/v2/users/{user}/profile \ | 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.User](schemas.md#codersdkuser) | To perform this operation, you must be authenticated. [Learn more](authentication.md). + +## Activate user account + +### Code samples + +```shell +# Example request using curl +curl -X PUT http://coder-server:8080/api/v2/users/{user}/status/activate \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`PUT /users/{user}/status/activate` + +### Parameters + +| Name | In | Type | Required | Description | +| ------ | ---- | ------ | -------- | -------------------- | +| `user` | path | string | true | User ID, name, or me | + +### Example responses + +> 200 Response + +```json +{ + "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" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ---------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.User](schemas.md#codersdkuser) | + +To perform this operation, you must be authenticated. [Learn more](authentication.md). + +## Suspend user account + +### Code samples + +```shell +# Example request using curl +curl -X PUT http://coder-server:8080/api/v2/users/{user}/status/suspend \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`PUT /users/{user}/status/suspend` + +### Parameters + +| Name | In | Type | Required | Description | +| ------ | ---- | ------ | -------- | -------------------- | +| `user` | path | string | true | User ID, name, or me | + +### Example responses + +> 200 Response + +```json +{ + "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" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ---------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.User](schemas.md#codersdkuser) | + +To perform this operation, you must be authenticated. [Learn more](authentication.md). From b1f389babde24f25c857b6bdf96e2e52f36e2c01 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Mon, 9 Jan 2023 11:36:16 +0100 Subject: [PATCH 28/36] User roles --- coderd/apidoc/docs.go | 190 ++++++++++++++++++++++++++++++++--- coderd/apidoc/swagger.json | 170 +++++++++++++++++++++++++++++--- coderd/members.go | 4 +- coderd/users.go | 29 +++++- docs/api/members.md | 10 +- docs/api/schemas.md | 16 +++ docs/api/users.md | 197 +++++++++++++++++++++++++++++++++++++ 7 files changed, 582 insertions(+), 34 deletions(-) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 3760b4972eaeb..7f2729b15b9b2 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -507,13 +507,11 @@ const docTemplate = `{ "operationId": "assign-role-to-organization-member", "parameters": [ { - "description": "Update roles request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateRoles" - } + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true }, { "type": "string", @@ -523,11 +521,13 @@ const docTemplate = `{ "required": true }, { - "type": "string", - "description": "Username, UUID, or me", - "name": "user", - "in": "path", - "required": true + "description": "Update roles request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateRoles" + } } ], "responses": { @@ -2127,7 +2127,7 @@ const docTemplate = `{ } }, "/users/{user}": { - "delete": { + "get": { "security": [ { "CoderSessionToken": [] @@ -2158,6 +2158,78 @@ const docTemplate = `{ } } } + }, + "delete": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Delete user", + "operationId": "delete-user", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.User" + } + } + } + } + }, + "/users/{user}/password": { + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Update user password", + "operationId": "update-user-password", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "description": "Update password request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateUserPasswordRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + } + } } }, "/users/{user}/profile": { @@ -2203,6 +2275,84 @@ const docTemplate = `{ } } }, + "/users/{user}/roles": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Get user roles", + "operationId": "get-user-roles", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.User" + } + } + } + }, + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Assign role to user", + "operationId": "assign-role-to-user", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "description": "Update roles request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateRoles" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.User" + } + } + } + } + }, "/users/{user}/status/activate": { "put": { "security": [ @@ -4985,6 +5135,20 @@ const docTemplate = `{ } } }, + "codersdk.UpdateUserPasswordRequest": { + "type": "object", + "required": [ + "password" + ], + "properties": { + "old_password": { + "type": "string" + }, + "password": { + "type": "string" + } + } + }, "codersdk.UpdateUserProfileRequest": { "type": "object", "required": [ diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 85de35c654d58..027509059fdb6 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -435,13 +435,11 @@ "operationId": "assign-role-to-organization-member", "parameters": [ { - "description": "Update roles request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateRoles" - } + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true }, { "type": "string", @@ -451,11 +449,13 @@ "required": true }, { - "type": "string", - "description": "Username, UUID, or me", - "name": "user", - "in": "path", - "required": true + "description": "Update roles request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateRoles" + } } ], "responses": { @@ -1867,7 +1867,7 @@ } }, "/users/{user}": { - "delete": { + "get": { "security": [ { "CoderSessionToken": [] @@ -1894,6 +1894,70 @@ } } } + }, + "delete": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Delete user", + "operationId": "delete-user", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.User" + } + } + } + } + }, + "/users/{user}/password": { + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Update user password", + "operationId": "update-user-password", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "description": "Update password request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateUserPasswordRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + } + } } }, "/users/{user}/profile": { @@ -1935,6 +1999,74 @@ } } }, + "/users/{user}/roles": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Get user roles", + "operationId": "get-user-roles", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.User" + } + } + } + }, + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Assign role to user", + "operationId": "assign-role-to-user", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "description": "Update roles request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateRoles" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.User" + } + } + } + } + }, "/users/{user}/status/activate": { "put": { "security": [ @@ -4505,6 +4637,18 @@ } } }, + "codersdk.UpdateUserPasswordRequest": { + "type": "object", + "required": ["password"], + "properties": { + "old_password": { + "type": "string" + }, + "password": { + "type": "string" + } + } + }, "codersdk.UpdateUserProfileRequest": { "type": "object", "required": ["username"], diff --git a/coderd/members.go b/coderd/members.go index 9141cadb6a0b3..0cba45b723639 100644 --- a/coderd/members.go +++ b/coderd/members.go @@ -22,9 +22,9 @@ import ( // @Accept json // @Produce json // @Tags Members -// @Param request body codersdk.UpdateRoles true "Update roles request" +// @Param user path string true "User ID, name, or me" // @Param organization path string true "Organization ID" -// @Param user path string true "Username, UUID, or me" +// @Param request body codersdk.UpdateRoles true "Update roles request" // @Success 200 {object} codersdk.OrganizationMember // @Router /organizations/{organization}/members/{user}/roles [put] func (api *API) putMemberRoles(rw http.ResponseWriter, r *http.Request) { diff --git a/coderd/users.go b/coderd/users.go index 510fad34aab70..093681c55ceb5 100644 --- a/coderd/users.go +++ b/coderd/users.go @@ -410,7 +410,7 @@ func (api *API) deleteUser(rw http.ResponseWriter, r *http.Request) { // @Tags Users // @Param user path string true "User ID, name, or me" // @Success 200 {object} codersdk.User -// @Router /users/{user} [delete] +// @Router /users/{user} [get] func (api *API) userByName(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() user := httpmw.UserParam(r) @@ -614,6 +614,15 @@ func (api *API) putUserStatus(status database.UserStatus) func(rw http.ResponseW } } +// @Summary Update user password +// @ID update-user-password +// @Security CoderSessionToken +// @Produce json +// @Tags Users +// @Param user path string true "User ID, name, or me" +// @Param request body codersdk.UpdateUserPasswordRequest true "Update password request" +// @Success 204 +// @Router /users/{user}/password [put] func (api *API) putUserPassword(rw http.ResponseWriter, r *http.Request) { var ( ctx = r.Context() @@ -731,6 +740,14 @@ func (api *API) putUserPassword(rw http.ResponseWriter, r *http.Request) { httpapi.Write(ctx, rw, http.StatusNoContent, nil) } +// @Summary Get user roles +// @ID get-user-roles +// @Security CoderSessionToken +// @Produce json +// @Tags Users +// @Param user path string true "User ID, name, or me" +// @Success 200 {object} codersdk.User +// @Router /users/{user}/roles [get] func (api *API) userRoles(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() user := httpmw.UserParam(r) @@ -774,6 +791,16 @@ func (api *API) userRoles(rw http.ResponseWriter, r *http.Request) { httpapi.Write(ctx, rw, http.StatusOK, resp) } +// @Summary Assign role to user +// @ID assign-role-to-user +// @Security CoderSessionToken +// @Accept json +// @Produce json +// @Tags Users +// @Param user path string true "User ID, name, or me" +// @Param request body codersdk.UpdateRoles true "Update roles request" +// @Success 200 {object} codersdk.User +// @Router /users/{user}/roles [put] func (api *API) putUserRoles(rw http.ResponseWriter, r *http.Request) { var ( ctx = r.Context() diff --git a/docs/api/members.md b/docs/api/members.md index 4b6d47095de6b..21eea27021292 100644 --- a/docs/api/members.md +++ b/docs/api/members.md @@ -78,11 +78,11 @@ curl -X PUT http://coder-server:8080/api/v2/organizations/{organization}/members ### Parameters -| Name | In | Type | Required | Description | -| -------------- | ---- | ------------------------------------------------------ | -------- | --------------------- | -| `organization` | path | string | true | Organization ID | -| `user` | path | string | true | Username, UUID, or me | -| `body` | body | [codersdk.UpdateRoles](schemas.md#codersdkupdateroles) | true | Update roles request | +| Name | In | Type | Required | Description | +| -------------- | ---- | ------------------------------------------------------ | -------- | -------------------- | +| `user` | path | string | true | User ID, name, or me | +| `organization` | path | string | true | Organization ID | +| `body` | body | [codersdk.UpdateRoles](schemas.md#codersdkupdateroles) | true | Update roles request | ### Example responses diff --git a/docs/api/schemas.md b/docs/api/schemas.md index ce5ab4c256317..1018c7d41981b 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -3377,6 +3377,22 @@ Parameter represents a set value for the scope. | ------- | --------------- | -------- | ------------ | ----------- | | `roles` | array of string | false | | | +## codersdk.UpdateUserPasswordRequest + +```json +{ + "old_password": "string", + "password": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| -------------- | ------ | -------- | ------------ | ----------- | +| `old_password` | string | false | | | +| `password` | string | true | | | + ## codersdk.UpdateUserProfileRequest ```json diff --git a/docs/api/users.md b/docs/api/users.md index 2c07230967b20..33fb7fd02a1c7 100644 --- a/docs/api/users.md +++ b/docs/api/users.md @@ -325,6 +325,56 @@ To perform this operation, you must be authenticated. [Learn more](authenticatio ### Code samples +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/users/{user} \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /users/{user}` + +### Parameters + +| Name | In | Type | Required | Description | +| ------ | ---- | ------ | -------- | -------------------- | +| `user` | path | string | true | User ID, name, or me | + +### Example responses + +> 200 Response + +```json +{ + "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" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ---------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.User](schemas.md#codersdkuser) | + +To perform this operation, you must be authenticated. [Learn more](authentication.md). + +## Delete user + +### Code samples + ```shell # Example request using curl curl -X DELETE http://coder-server:8080/api/v2/users/{user} \ @@ -371,6 +421,43 @@ curl -X DELETE http://coder-server:8080/api/v2/users/{user} \ To perform this operation, you must be authenticated. [Learn more](authentication.md). +## Update user password + +### Code samples + +```shell +# Example request using curl +curl -X PUT http://coder-server:8080/api/v2/users/{user}/password \ + -H 'Content-Type: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`PUT /users/{user}/password` + +> Body parameter + +```json +{ + "old_password": "string", + "password": "string" +} +``` + +### Parameters + +| Name | In | Type | Required | Description | +| ------ | ---- | ---------------------------------------------------------------------------------- | -------- | ----------------------- | +| `user` | path | string | true | User ID, name, or me | +| `body` | body | [codersdk.UpdateUserPasswordRequest](schemas.md#codersdkupdateuserpasswordrequest) | true | Update password request | + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | --------------------------------------------------------------- | ----------- | ------ | +| 204 | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) | No Content | | + +To perform this operation, you must be authenticated. [Learn more](authentication.md). + ## Update user profile ### Code samples @@ -431,6 +518,116 @@ curl -X PUT http://coder-server:8080/api/v2/users/{user}/profile \ To perform this operation, you must be authenticated. [Learn more](authentication.md). +## Get user roles + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/users/{user}/roles \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /users/{user}/roles` + +### Parameters + +| Name | In | Type | Required | Description | +| ------ | ---- | ------ | -------- | -------------------- | +| `user` | path | string | true | User ID, name, or me | + +### Example responses + +> 200 Response + +```json +{ + "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" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ---------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.User](schemas.md#codersdkuser) | + +To perform this operation, you must be authenticated. [Learn more](authentication.md). + +## Assign role to user + +### Code samples + +```shell +# Example request using curl +curl -X PUT http://coder-server:8080/api/v2/users/{user}/roles \ + -H 'Content-Type: application/json' \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`PUT /users/{user}/roles` + +> Body parameter + +```json +{ + "roles": ["string"] +} +``` + +### Parameters + +| Name | In | Type | Required | Description | +| ------ | ---- | ------------------------------------------------------ | -------- | -------------------- | +| `user` | path | string | true | User ID, name, or me | +| `body` | body | [codersdk.UpdateRoles](schemas.md#codersdkupdateroles) | true | Update roles request | + +### Example responses + +> 200 Response + +```json +{ + "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" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ---------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.User](schemas.md#codersdkuser) | + +To perform this operation, you must be authenticated. [Learn more](authentication.md). + ## Activate user account ### Code samples From 14a1654983d7160bbc7977c32591a0b535a2f1ab Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Mon, 9 Jan 2023 11:48:44 +0100 Subject: [PATCH 29/36] User tokens --- coderd/apidoc/docs.go | 194 +++++++++++++++++++++++++++++++++++++ coderd/apidoc/swagger.json | 171 ++++++++++++++++++++++++++++++++ coderd/apikey.go | 27 ++++++ codersdk/apikey.go | 16 +-- docs/api/schemas.md | 78 +++++++++++++++ docs/api/users.md | 160 ++++++++++++++++++++++++++++++ 6 files changed, 638 insertions(+), 8 deletions(-) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 7f2729b15b9b2..cc9210f9be314 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -2192,6 +2192,118 @@ const docTemplate = `{ } } }, + "/users/{user}/keys": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Create new session key", + "operationId": "create-new-session-key", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.GenerateAPIKeyResponse" + } + } + } + } + }, + "/users/{user}/keys/tokens": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Get user tokens", + "operationId": "get-user-tokens", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.APIKey" + } + } + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Create token API key", + "operationId": "create-token-api-key", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "description": "Create token request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateTokenRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.GenerateAPIKeyResponse" + } + } + } + } + }, "/users/{user}/password": { "put": { "security": [ @@ -3444,6 +3556,65 @@ const docTemplate = `{ } } }, + "codersdk.APIKey": { + "type": "object", + "required": [ + "created_at", + "expires_at", + "id", + "last_used", + "lifetime_seconds", + "login_type", + "scope", + "updated_at", + "user_id" + ], + "properties": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "expires_at": { + "type": "string", + "format": "date-time" + }, + "id": { + "type": "string" + }, + "last_used": { + "type": "string", + "format": "date-time" + }, + "lifetime_seconds": { + "type": "integer" + }, + "login_type": { + "type": "string", + "enum": [ + "password", + "github", + "oidc", + "token" + ] + }, + "scope": { + "type": "string", + "enum": [ + "all", + "application_connect" + ] + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "user_id": { + "description": "NOTE: do not ever return the HashedSecret", + "type": "string", + "format": "uuid" + } + } + }, "codersdk.AWSInstanceIdentityToken": { "type": "object", "required": [ @@ -3895,6 +4066,21 @@ const docTemplate = `{ } } }, + "codersdk.CreateTokenRequest": { + "type": "object", + "properties": { + "lifetime": { + "type": "integer" + }, + "scope": { + "type": "string", + "enum": [ + "all", + "application_connect" + ] + } + } + }, "codersdk.CreateUserRequest": { "type": "object", "required": [ @@ -4330,6 +4516,14 @@ const docTemplate = `{ } } }, + "codersdk.GenerateAPIKeyResponse": { + "type": "object", + "properties": { + "key": { + "type": "string" + } + } + }, "codersdk.GetAppHostResponse": { "type": "object", "properties": { diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 027509059fdb6..c673cf4fe922d 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -1924,6 +1924,106 @@ } } }, + "/users/{user}/keys": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Create new session key", + "operationId": "create-new-session-key", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.GenerateAPIKeyResponse" + } + } + } + } + }, + "/users/{user}/keys/tokens": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Get user tokens", + "operationId": "get-user-tokens", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.APIKey" + } + } + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Create token API key", + "operationId": "create-token-api-key", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "description": "Create token request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateTokenRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.GenerateAPIKeyResponse" + } + } + } + } + }, "/users/{user}/password": { "put": { "security": [ @@ -3031,6 +3131,57 @@ } } }, + "codersdk.APIKey": { + "type": "object", + "required": [ + "created_at", + "expires_at", + "id", + "last_used", + "lifetime_seconds", + "login_type", + "scope", + "updated_at", + "user_id" + ], + "properties": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "expires_at": { + "type": "string", + "format": "date-time" + }, + "id": { + "type": "string" + }, + "last_used": { + "type": "string", + "format": "date-time" + }, + "lifetime_seconds": { + "type": "integer" + }, + "login_type": { + "type": "string", + "enum": ["password", "github", "oidc", "token"] + }, + "scope": { + "type": "string", + "enum": ["all", "application_connect"] + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "user_id": { + "description": "NOTE: do not ever return the HashedSecret", + "type": "string", + "format": "uuid" + } + } + }, "codersdk.AWSInstanceIdentityToken": { "type": "object", "required": ["document", "signature"], @@ -3449,6 +3600,18 @@ } } }, + "codersdk.CreateTokenRequest": { + "type": "object", + "properties": { + "lifetime": { + "type": "integer" + }, + "scope": { + "type": "string", + "enum": ["all", "application_connect"] + } + } + }, "codersdk.CreateUserRequest": { "type": "object", "required": ["email", "organization_id", "password", "username"], @@ -3872,6 +4035,14 @@ } } }, + "codersdk.GenerateAPIKeyResponse": { + "type": "object", + "properties": { + "key": { + "type": "string" + } + } + }, "codersdk.GetAppHostResponse": { "type": "object", "properties": { diff --git a/coderd/apikey.go b/coderd/apikey.go index 2900f8e4abe62..95c28041f63a3 100644 --- a/coderd/apikey.go +++ b/coderd/apikey.go @@ -25,6 +25,16 @@ import ( ) // Creates a new token API key that effectively doesn't expire. +// +// @Summary Create token API key +// @ID create-token-api-key +// @Security CoderSessionToken +// @Produce json +// @Tags Users +// @Param user path string true "User ID, name, or me" +// @Param request body codersdk.CreateTokenRequest true "Create token request" +// @Success 201 {object} codersdk.GenerateAPIKeyResponse +// @Router /users/{user}/keys/tokens [post] func (api *API) postToken(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() user := httpmw.UserParam(r) @@ -78,6 +88,15 @@ func (api *API) postToken(rw http.ResponseWriter, r *http.Request) { } // Creates a new session key, used for logging in via the CLI. +// +// @Summary Create new session key +// @ID create-new-session-key +// @Security CoderSessionToken +// @Produce json +// @Tags Users +// @Param user path string true "User ID, name, or me" +// @Success 201 {object} codersdk.GenerateAPIKeyResponse +// @Router /users/{user}/keys [post] func (api *API) postAPIKey(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() user := httpmw.UserParam(r) @@ -140,6 +159,14 @@ func (api *API) apiKey(rw http.ResponseWriter, r *http.Request) { httpapi.Write(ctx, rw, http.StatusOK, convertAPIKey(key)) } +// @Summary Get user tokens +// @ID get-user-tokens +// @Security CoderSessionToken +// @Produce json +// @Tags Users +// @Param user path string true "User ID, name, or me" +// @Success 200 {array} codersdk.APIKey +// @Router /users/{user}/keys/tokens [get] func (api *API) tokens(rw http.ResponseWriter, r *http.Request) { var ( ctx = r.Context() diff --git a/codersdk/apikey.go b/codersdk/apikey.go index 8fa0180e7b2b8..fd896a0d29b4a 100644 --- a/codersdk/apikey.go +++ b/codersdk/apikey.go @@ -13,13 +13,13 @@ import ( type APIKey struct { ID string `json:"id" validate:"required"` // NOTE: do not ever return the HashedSecret - UserID uuid.UUID `json:"user_id" validate:"required"` - LastUsed time.Time `json:"last_used" validate:"required"` - ExpiresAt time.Time `json:"expires_at" validate:"required"` - CreatedAt time.Time `json:"created_at" validate:"required"` - UpdatedAt time.Time `json:"updated_at" validate:"required"` - LoginType LoginType `json:"login_type" validate:"required"` - Scope APIKeyScope `json:"scope" validate:"required"` + UserID uuid.UUID `json:"user_id" validate:"required" format:"uuid"` + LastUsed time.Time `json:"last_used" validate:"required" format:"date-time"` + ExpiresAt time.Time `json:"expires_at" validate:"required" format:"date-time"` + CreatedAt time.Time `json:"created_at" validate:"required" format:"date-time"` + UpdatedAt time.Time `json:"updated_at" validate:"required" format:"date-time"` + LoginType LoginType `json:"login_type" validate:"required" enums:"password,github,oidc,token"` + Scope APIKeyScope `json:"scope" validate:"required" enums:"all,application_connect"` LifetimeSeconds int64 `json:"lifetime_seconds" validate:"required"` } @@ -41,7 +41,7 @@ const ( type CreateTokenRequest struct { Lifetime time.Duration `json:"lifetime"` - Scope APIKeyScope `json:"scope"` + Scope APIKeyScope `json:"scope" enums:"all,application_connect"` } // GenerateAPIKeyResponse contains an API key for a user. diff --git a/docs/api/schemas.md b/docs/api/schemas.md index 1018c7d41981b..07ba125aae45c 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -16,6 +16,47 @@ | ------------ | ------ | -------- | ------------ | ----------- | | `csp-report` | object | false | | | +## codersdk.APIKey + +```json +{ + "created_at": "2019-08-24T14:15:22Z", + "expires_at": "2019-08-24T14:15:22Z", + "id": "string", + "last_used": "2019-08-24T14:15:22Z", + "lifetime_seconds": 0, + "login_type": "password", + "scope": "all", + "updated_at": "2019-08-24T14:15:22Z", + "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ------------------ | ------- | -------- | ------------ | ------------------------------------------- | +| `created_at` | string | true | | | +| `expires_at` | string | true | | | +| `id` | string | true | | | +| `last_used` | string | true | | | +| `lifetime_seconds` | integer | true | | | +| `login_type` | string | true | | | +| `scope` | string | true | | | +| `updated_at` | string | true | | | +| `user_id` | string | true | | User ID do not ever return the HashedSecret | + +#### Enumerated Values + +| Property | Value | +| ------------ | --------------------- | +| `login_type` | `password` | +| `login_type` | `github` | +| `login_type` | `oidc` | +| `login_type` | `token` | +| `scope` | `all` | +| `scope` | `application_connect` | + ## codersdk.AWSInstanceIdentityToken ```json @@ -623,6 +664,29 @@ CreateParameterRequest is a structure used to create a new parameter value for a | `resource_type` | `api_key` | | `resource_type` | `group` | +## codersdk.CreateTokenRequest + +```json +{ + "lifetime": 0, + "scope": "all" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ---------- | ------- | -------- | ------------ | ----------- | +| `lifetime` | integer | false | | | +| `scope` | string | false | | | + +#### Enumerated Values + +| Property | Value | +| -------- | --------------------- | +| `scope` | `all` | +| `scope` | `application_connect` | + ## codersdk.CreateUserRequest ```json @@ -2018,6 +2082,20 @@ CreateParameterRequest is a structure used to create a new parameter value for a | `usage` | string | false | | | | `value` | integer | false | | | +## codersdk.GenerateAPIKeyResponse + +```json +{ + "key": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ----- | ------ | -------- | ------------ | ----------- | +| `key` | string | false | | | + ## codersdk.GetAppHostResponse ```json diff --git a/docs/api/users.md b/docs/api/users.md index 33fb7fd02a1c7..5817ad064e372 100644 --- a/docs/api/users.md +++ b/docs/api/users.md @@ -421,6 +421,166 @@ curl -X DELETE http://coder-server:8080/api/v2/users/{user} \ To perform this operation, you must be authenticated. [Learn more](authentication.md). +## Create new session key + +### Code samples + +```shell +# Example request using curl +curl -X POST http://coder-server:8080/api/v2/users/{user}/keys \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`POST /users/{user}/keys` + +### Parameters + +| Name | In | Type | Required | Description | +| ------ | ---- | ------ | -------- | -------------------- | +| `user` | path | string | true | User ID, name, or me | + +### Example responses + +> 201 Response + +```json +{ + "key": "string" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------------ | ----------- | ---------------------------------------------------------------------------- | +| 201 | [Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) | Created | [codersdk.GenerateAPIKeyResponse](schemas.md#codersdkgenerateapikeyresponse) | + +To perform this operation, you must be authenticated. [Learn more](authentication.md). + +## Get user tokens + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/users/{user}/keys/tokens \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /users/{user}/keys/tokens` + +### Parameters + +| Name | In | Type | Required | Description | +| ------ | ---- | ------ | -------- | -------------------- | +| `user` | path | string | true | User ID, name, or me | + +### Example responses + +> 200 Response + +```json +[ + { + "created_at": "2019-08-24T14:15:22Z", + "expires_at": "2019-08-24T14:15:22Z", + "id": "string", + "last_used": "2019-08-24T14:15:22Z", + "lifetime_seconds": 0, + "login_type": "password", + "scope": "all", + "updated_at": "2019-08-24T14:15:22Z", + "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5" + } +] +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ----------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | array of [codersdk.APIKey](schemas.md#codersdkapikey) | + +

Response Schema

+ +Status Code **200** + +| Name | Type | Required | Restrictions | Description | +| -------------------- | ----------------- | -------- | ------------ | ----------------------------------------- | +| `[array item]` | array | false | | | +| `» created_at` | string(date-time) | true | | | +| `» expires_at` | string(date-time) | true | | | +| `» id` | string | true | | | +| `» last_used` | string(date-time) | true | | | +| `» lifetime_seconds` | integer | true | | | +| `» login_type` | string | true | | | +| `» scope` | string | true | | | +| `» updated_at` | string(date-time) | true | | | +| `» user_id` | string(uuid) | true | | NOTE: do not ever return the HashedSecret | + +#### Enumerated Values + +| Property | Value | +| ------------ | --------------------- | +| `login_type` | `password` | +| `login_type` | `github` | +| `login_type` | `oidc` | +| `login_type` | `token` | +| `scope` | `all` | +| `scope` | `application_connect` | + +To perform this operation, you must be authenticated. [Learn more](authentication.md). + +## Create token API key + +### Code samples + +```shell +# Example request using curl +curl -X POST http://coder-server:8080/api/v2/users/{user}/keys/tokens \ + -H 'Content-Type: application/json' \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`POST /users/{user}/keys/tokens` + +> Body parameter + +```json +{ + "lifetime": 0, + "scope": "all" +} +``` + +### Parameters + +| Name | In | Type | Required | Description | +| ------ | ---- | -------------------------------------------------------------------- | -------- | -------------------- | +| `user` | path | string | true | User ID, name, or me | +| `body` | body | [codersdk.CreateTokenRequest](schemas.md#codersdkcreatetokenrequest) | true | Create token request | + +### Example responses + +> 201 Response + +```json +{ + "key": "string" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------------ | ----------- | ---------------------------------------------------------------------------- | +| 201 | [Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) | Created | [codersdk.GenerateAPIKeyResponse](schemas.md#codersdkgenerateapikeyresponse) | + +To perform this operation, you must be authenticated. [Learn more](authentication.md). + ## Update user password ### Code samples From 5c2262926f546d73b99fa167f3e15e26fa17fdda Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Mon, 9 Jan 2023 11:51:07 +0100 Subject: [PATCH 30/36] Keys --- coderd/apidoc/docs.go | 79 ++++++++++++++++++++++++++++++++++++++ coderd/apidoc/swagger.json | 71 ++++++++++++++++++++++++++++++++++ coderd/apikey.go | 18 +++++++++ docs/api/users.md | 73 +++++++++++++++++++++++++++++++++++ 4 files changed, 241 insertions(+) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index cc9210f9be314..7bd07c4cd389f 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -2304,6 +2304,85 @@ const docTemplate = `{ } } }, + "/users/{user}/keys/{keyid}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Get API key", + "operationId": "get-user-tokens", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "Key ID", + "name": "keyid", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.APIKey" + } + } + } + }, + "delete": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Delete API key", + "operationId": "delete-user-tokens", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "Key ID", + "name": "keyid", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, "/users/{user}/password": { "put": { "security": [ diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index c673cf4fe922d..e55dca1a8481a 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -2024,6 +2024,77 @@ } } }, + "/users/{user}/keys/{keyid}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Get API key", + "operationId": "get-user-tokens", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "Key ID", + "name": "keyid", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.APIKey" + } + } + } + }, + "delete": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Delete API key", + "operationId": "delete-user-tokens", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "Key ID", + "name": "keyid", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, "/users/{user}/password": { "put": { "security": [ diff --git a/coderd/apikey.go b/coderd/apikey.go index 95c28041f63a3..d759794e73838 100644 --- a/coderd/apikey.go +++ b/coderd/apikey.go @@ -131,6 +131,15 @@ func (api *API) postAPIKey(rw http.ResponseWriter, r *http.Request) { httpapi.Write(ctx, rw, http.StatusCreated, codersdk.GenerateAPIKeyResponse{Key: cookie.Value}) } +// @Summary Get API key +// @ID get-user-tokens +// @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) +// @Success 200 {object} codersdk.APIKey +// @Router /users/{user}/keys/{keyid} [get] func (api *API) apiKey(rw http.ResponseWriter, r *http.Request) { var ( ctx = r.Context() @@ -199,6 +208,15 @@ func (api *API) tokens(rw http.ResponseWriter, r *http.Request) { httpapi.Write(ctx, rw, http.StatusOK, apiKeys) } +// @Summary Delete API key +// @ID delete-user-tokens +// @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) +// @Success 204 +// @Router /users/{user}/keys/{keyid} [delete] func (api *API) deleteAPIKey(rw http.ResponseWriter, r *http.Request) { var ( ctx = r.Context() diff --git a/docs/api/users.md b/docs/api/users.md index 5817ad064e372..f1c1880ac0596 100644 --- a/docs/api/users.md +++ b/docs/api/users.md @@ -581,6 +581,79 @@ curl -X POST http://coder-server:8080/api/v2/users/{user}/keys/tokens \ To perform this operation, you must be authenticated. [Learn more](authentication.md). +## Get API key + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/users/{user}/keys/{keyid} \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /users/{user}/keys/{keyid}` + +### Parameters + +| Name | In | Type | Required | Description | +| ------- | ---- | ------------ | -------- | -------------------- | +| `user` | path | string | true | User ID, name, or me | +| `keyid` | path | string(uuid) | true | Key ID | + +### Example responses + +> 200 Response + +```json +{ + "created_at": "2019-08-24T14:15:22Z", + "expires_at": "2019-08-24T14:15:22Z", + "id": "string", + "last_used": "2019-08-24T14:15:22Z", + "lifetime_seconds": 0, + "login_type": "password", + "scope": "all", + "updated_at": "2019-08-24T14:15:22Z", + "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | -------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.APIKey](schemas.md#codersdkapikey) | + +To perform this operation, you must be authenticated. [Learn more](authentication.md). + +## Delete API key + +### Code samples + +```shell +# Example request using curl +curl -X DELETE http://coder-server:8080/api/v2/users/{user}/keys/{keyid} \ + -H 'Coder-Session-Token: API_KEY' +``` + +`DELETE /users/{user}/keys/{keyid}` + +### Parameters + +| Name | In | Type | Required | Description | +| ------- | ---- | ------------ | -------- | -------------------- | +| `user` | path | string | true | User ID, name, or me | +| `keyid` | path | string(uuid) | true | Key ID | + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | --------------------------------------------------------------- | ----------- | ------ | +| 204 | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) | No Content | | + +To perform this operation, you must be authenticated. [Learn more](authentication.md). + ## Update user password ### Code samples From 91c78f43ffb6396f03f82f946e167d4d13a77ce0 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Mon, 9 Jan 2023 11:56:47 +0100 Subject: [PATCH 31/36] SSH key --- coderd/apidoc/docs.go | 86 ++++++++++++++++++++++++++++++++++++++ coderd/apidoc/swagger.json | 78 ++++++++++++++++++++++++++++++++++ coderd/gitsshkey.go | 16 +++++++ codersdk/gitsshkey.go | 6 +-- docs/api/schemas.md | 20 +++++++++ docs/api/users.md | 80 +++++++++++++++++++++++++++++++++++ 6 files changed, 283 insertions(+), 3 deletions(-) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 7bd07c4cd389f..2bbf76f8294dd 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -2192,6 +2192,72 @@ const docTemplate = `{ } } }, + "/users/{user}/gitsshkey": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Get user Git SSH key", + "operationId": "get-user-git-ssh-key", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.GitSSHKey" + } + } + } + }, + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Regenerate user SSH key", + "operationId": "regenerate-user-ssh-key", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.GitSSHKey" + } + } + } + } + }, "/users/{user}/keys": { "post": { "security": [ @@ -4661,6 +4727,26 @@ const docTemplate = `{ } } }, + "codersdk.GitSSHKey": { + "type": "object", + "properties": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "public_key": { + "type": "string" + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "user_id": { + "type": "string", + "format": "uuid" + } + } + }, "codersdk.GoogleInstanceIdentityToken": { "type": "object", "required": [ diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index e55dca1a8481a..736e74bbef4e1 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -1924,6 +1924,64 @@ } } }, + "/users/{user}/gitsshkey": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Get user Git SSH key", + "operationId": "get-user-git-ssh-key", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.GitSSHKey" + } + } + } + }, + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Regenerate user SSH key", + "operationId": "regenerate-user-ssh-key", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.GitSSHKey" + } + } + } + } + }, "/users/{user}/keys": { "post": { "security": [ @@ -4172,6 +4230,26 @@ } } }, + "codersdk.GitSSHKey": { + "type": "object", + "properties": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "public_key": { + "type": "string" + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "user_id": { + "type": "string", + "format": "uuid" + } + } + }, "codersdk.GoogleInstanceIdentityToken": { "type": "object", "required": ["json_web_token"], diff --git a/coderd/gitsshkey.go b/coderd/gitsshkey.go index a0f15da2e9e0c..9e68d7a64283d 100644 --- a/coderd/gitsshkey.go +++ b/coderd/gitsshkey.go @@ -12,6 +12,14 @@ import ( "github.com/coder/coder/codersdk" ) +// @Summary Regenerate user SSH key +// @ID regenerate-user-ssh-key +// @Security CoderSessionToken +// @Produce json +// @Tags Users +// @Param user path string true "User ID, name, or me" +// @Success 200 {object} codersdk.GitSSHKey +// @Router /users/{user}/gitsshkey [put] func (api *API) regenerateGitSSHKey(rw http.ResponseWriter, r *http.Request) { var ( ctx = r.Context() @@ -73,6 +81,14 @@ func (api *API) regenerateGitSSHKey(rw http.ResponseWriter, r *http.Request) { }) } +// @Summary Get user Git SSH key +// @ID get-user-git-ssh-key +// @Security CoderSessionToken +// @Produce json +// @Tags Users +// @Param user path string true "User ID, name, or me" +// @Success 200 {object} codersdk.GitSSHKey +// @Router /users/{user}/gitsshkey [get] func (api *API) gitSSHKey(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() user := httpmw.UserParam(r) diff --git a/codersdk/gitsshkey.go b/codersdk/gitsshkey.go index e345a2733ab02..4a19110b5bb90 100644 --- a/codersdk/gitsshkey.go +++ b/codersdk/gitsshkey.go @@ -12,9 +12,9 @@ import ( ) type GitSSHKey struct { - UserID uuid.UUID `json:"user_id"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + UserID uuid.UUID `json:"user_id" format:"uuid"` + CreatedAt time.Time `json:"created_at" format:"date-time"` + UpdatedAt time.Time `json:"updated_at" format:"date-time"` PublicKey string `json:"public_key"` } diff --git a/docs/api/schemas.md b/docs/api/schemas.md index 07ba125aae45c..08fc7bbc13624 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -2173,6 +2173,26 @@ CreateParameterRequest is a structure used to create a new parameter value for a | `type` | string | false | | | | `validate_url` | string | false | | | +## codersdk.GitSSHKey + +```json +{ + "created_at": "2019-08-24T14:15:22Z", + "public_key": "string", + "updated_at": "2019-08-24T14:15:22Z", + "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +| ------------ | ------ | -------- | ------------ | ----------- | +| `created_at` | string | false | | | +| `public_key` | string | false | | | +| `updated_at` | string | false | | | +| `user_id` | string | false | | | + ## codersdk.GoogleInstanceIdentityToken ```json diff --git a/docs/api/users.md b/docs/api/users.md index f1c1880ac0596..71e9ac7e791be 100644 --- a/docs/api/users.md +++ b/docs/api/users.md @@ -421,6 +421,86 @@ curl -X DELETE http://coder-server:8080/api/v2/users/{user} \ To perform this operation, you must be authenticated. [Learn more](authentication.md). +## Get user Git SSH key + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/users/{user}/gitsshkey \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /users/{user}/gitsshkey` + +### Parameters + +| Name | In | Type | Required | Description | +| ------ | ---- | ------ | -------- | -------------------- | +| `user` | path | string | true | User ID, name, or me | + +### Example responses + +> 200 Response + +```json +{ + "created_at": "2019-08-24T14:15:22Z", + "public_key": "string", + "updated_at": "2019-08-24T14:15:22Z", + "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | -------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.GitSSHKey](schemas.md#codersdkgitsshkey) | + +To perform this operation, you must be authenticated. [Learn more](authentication.md). + +## Regenerate user SSH key + +### Code samples + +```shell +# Example request using curl +curl -X PUT http://coder-server:8080/api/v2/users/{user}/gitsshkey \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`PUT /users/{user}/gitsshkey` + +### Parameters + +| Name | In | Type | Required | Description | +| ------ | ---- | ------ | -------- | -------------------- | +| `user` | path | string | true | User ID, name, or me | + +### Example responses + +> 200 Response + +```json +{ + "created_at": "2019-08-24T14:15:22Z", + "public_key": "string", + "updated_at": "2019-08-24T14:15:22Z", + "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | -------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.GitSSHKey](schemas.md#codersdkgitsshkey) | + +To perform this operation, you must be authenticated. [Learn more](authentication.md). + ## Create new session key ### Code samples From c06a6360788ace8091245057a097f273b2fb70e0 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Mon, 9 Jan 2023 12:14:37 +0100 Subject: [PATCH 32/36] All --- coderd/apidoc/docs.go | 135 ++++++++++++++++++++++++++++++++-- coderd/apidoc/swagger.json | 123 +++++++++++++++++++++++++++++-- coderd/apikey.go | 2 +- coderd/users.go | 18 +++++ coderd/workspacebuilds.go | 10 +++ coderd/workspaces.go | 6 +- codersdk/organizations.go | 6 +- docs/api/builds.md | 144 +++++++++++++++++++++++++++++++++++++ docs/api/users.md | 95 ++++++++++++++++++++++++ docs/api/workspaces.md | 4 +- docs/manifest.json | 8 +-- 11 files changed, 530 insertions(+), 21 deletions(-) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 2bbf76f8294dd..edbd05390fc49 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -2384,7 +2384,7 @@ const docTemplate = `{ "Users" ], "summary": "Get API key", - "operationId": "get-user-tokens", + "operationId": "get-api-key", "parameters": [ { "type": "string", @@ -2449,6 +2449,84 @@ const docTemplate = `{ } } }, + "/users/{user}/organizations": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Get organizations by user", + "operationId": "get-organizations-by-users", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Organization" + } + } + } + } + } + }, + "/users/{user}/organizations/{organizationname}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Get organization by user and organization name", + "operationId": "get-organization-by-user-and-organization-name", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Organization name", + "name": "organizationname", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Organization" + } + } + } + } + }, "/users/{user}/password": { "put": { "security": [ @@ -2691,12 +2769,12 @@ const docTemplate = `{ "tags": [ "Workspaces" ], - "summary": "Get workspace metadata by owner and workspace name", - "operationId": "get-workspace-metadata-by-owner-and-workspace-name", + "summary": "Get workspace metadata by user and workspace name", + "operationId": "get-workspace-metadata-by-user-and-workspace-name", "parameters": [ { "type": "string", - "description": "Owner username", + "description": "User ID, name, or me", "name": "user", "in": "path", "required": true @@ -2725,6 +2803,55 @@ const docTemplate = `{ } } }, + "/users/{user}/workspace/{workspacename}/builds/{buildnumber}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Builds" + ], + "summary": "Get workspace build by user, workspace name, and build number", + "operationId": "get-workspace-build-by-user-workspace-name-and-build-number", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Workspace name", + "name": "workspacename", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "number", + "description": "Build number", + "name": "buildnumber", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceBuild" + } + } + } + } + }, "/workspaceagents/aws-instance-identity": { "post": { "security": [ diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 736e74bbef4e1..2acda213e26b8 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -2092,7 +2092,7 @@ "produces": ["application/json"], "tags": ["Users"], "summary": "Get API key", - "operationId": "get-user-tokens", + "operationId": "get-api-key", "parameters": [ { "type": "string", @@ -2153,6 +2153,76 @@ } } }, + "/users/{user}/organizations": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Get organizations by user", + "operationId": "get-organizations-by-users", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Organization" + } + } + } + } + } + }, + "/users/{user}/organizations/{organizationname}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Get organization by user and organization name", + "operationId": "get-organization-by-user-and-organization-name", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Organization name", + "name": "organizationname", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Organization" + } + } + } + } + }, "/users/{user}/password": { "put": { "security": [ @@ -2365,12 +2435,12 @@ ], "produces": ["application/json"], "tags": ["Workspaces"], - "summary": "Get workspace metadata by owner and workspace name", - "operationId": "get-workspace-metadata-by-owner-and-workspace-name", + "summary": "Get workspace metadata by user and workspace name", + "operationId": "get-workspace-metadata-by-user-and-workspace-name", "parameters": [ { "type": "string", - "description": "Owner username", + "description": "User ID, name, or me", "name": "user", "in": "path", "required": true @@ -2399,6 +2469,51 @@ } } }, + "/users/{user}/workspace/{workspacename}/builds/{buildnumber}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Builds"], + "summary": "Get workspace build by user, workspace name, and build number", + "operationId": "get-workspace-build-by-user-workspace-name-and-build-number", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Workspace name", + "name": "workspacename", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "number", + "description": "Build number", + "name": "buildnumber", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceBuild" + } + } + } + } + }, "/workspaceagents/aws-instance-identity": { "post": { "security": [ diff --git a/coderd/apikey.go b/coderd/apikey.go index d759794e73838..47ffcd201576e 100644 --- a/coderd/apikey.go +++ b/coderd/apikey.go @@ -132,7 +132,7 @@ func (api *API) postAPIKey(rw http.ResponseWriter, r *http.Request) { } // @Summary Get API key -// @ID get-user-tokens +// @ID get-api-key // @Security CoderSessionToken // @Produce json // @Tags Users diff --git a/coderd/users.go b/coderd/users.go index 093681c55ceb5..3e6acf34d02c7 100644 --- a/coderd/users.go +++ b/coderd/users.go @@ -906,6 +906,15 @@ 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 +// @Security CoderSessionToken +// @Produce json +// @Tags Users +// @Param user path string true "User ID, name, or me" +// @Success 200 {array} codersdk.Organization +// @Router /users/{user}/organizations [get] func (api *API) organizationsByUser(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() user := httpmw.UserParam(r) @@ -941,6 +950,15 @@ func (api *API) organizationsByUser(rw http.ResponseWriter, r *http.Request) { httpapi.Write(ctx, rw, http.StatusOK, publicOrganizations) } +// @Summary Get organization by user and organization name +// @ID get-organization-by-user-and-organization-name +// @Security CoderSessionToken +// @Produce json +// @Tags Users +// @Param user path string true "User ID, name, or me" +// @Param organizationname path string true "Organization name" +// @Success 200 {object} codersdk.Organization +// @Router /users/{user}/organizations/{organizationname} [get] func (api *API) organizationByUserAndName(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() organizationName := chi.URLParam(r, "organizationname") diff --git a/coderd/workspacebuilds.go b/coderd/workspacebuilds.go index 4f057786ddfe1..3d3d42b7ea2a1 100644 --- a/coderd/workspacebuilds.go +++ b/coderd/workspacebuilds.go @@ -191,6 +191,16 @@ func (api *API) workspaceBuilds(rw http.ResponseWriter, r *http.Request) { httpapi.Write(ctx, rw, http.StatusOK, apiBuilds) } +// @Summary Get workspace build by user, workspace name, and build number +// @ID get-workspace-build-by-user-workspace-name-and-build-number +// @Security CoderSessionToken +// @Produce json +// @Tags Builds +// @Param user path string true "User ID, name, or me" +// @Param workspacename path string true "Workspace name" +// @Param buildnumber path string true "Build number" format(number) +// @Success 200 {object} codersdk.WorkspaceBuild +// @Router /users/{user}/workspace/{workspacename}/builds/{buildnumber} [get] func (api *API) workspaceBuildByBuildNumber(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() owner := httpmw.UserParam(r) diff --git a/coderd/workspaces.go b/coderd/workspaces.go index 6edd0d13c629b..6ef629fe47bd0 100644 --- a/coderd/workspaces.go +++ b/coderd/workspaces.go @@ -192,12 +192,12 @@ func (api *API) workspaces(rw http.ResponseWriter, r *http.Request) { }) } -// @Summary Get workspace metadata by owner and workspace name -// @ID get-workspace-metadata-by-owner-and-workspace-name +// @Summary Get workspace metadata by user and workspace name +// @ID get-workspace-metadata-by-user-and-workspace-name // @Security CoderSessionToken // @Produce json // @Tags Workspaces -// @Param user path string true "Owner username" +// @Param user path string true "User ID, name, or me" // @Param workspacename path string true "Workspace name" // @Param include_deleted query bool false "Return data instead of HTTP 404 if the workspace is deleted" // @Success 200 {object} codersdk.Workspace diff --git a/codersdk/organizations.go b/codersdk/organizations.go index 39b50da013ec5..27a30f8a14583 100644 --- a/codersdk/organizations.go +++ b/codersdk/organizations.go @@ -36,9 +36,9 @@ type Organization struct { type CreateTemplateVersionRequest struct { Name string `json:"name,omitempty" validate:"omitempty,template_name"` // TemplateID optionally associates a version with a template. - TemplateID uuid.UUID `json:"template_id,omitempty"` - StorageMethod ProvisionerStorageMethod `json:"storage_method" validate:"oneof=file,required"` - FileID uuid.UUID `json:"file_id,omitempty" validate:"required_without=ExampleID"` + TemplateID uuid.UUID `json:"template_id,omitempty" format:"uuid"` + StorageMethod ProvisionerStorageMethod `json:"storage_method" validate:"oneof=file,required" enums:"file"` + FileID uuid.UUID `json:"file_id,omitempty" validate:"required_without=ExampleID" format:"uuid"` ExampleID string `json:"example_id,omitempty" validate:"required_without=FileID"` Provisioner ProvisionerType `json:"provisioner" validate:"oneof=terraform echo,required"` ProvisionerTags map[string]string `json:"tags"` diff --git a/docs/api/builds.md b/docs/api/builds.md index 366292529d971..5a58c4b33291f 100644 --- a/docs/api/builds.md +++ b/docs/api/builds.md @@ -2,6 +2,150 @@ > This page is incomplete, stay tuned. +## Get workspace build by user, workspace name, and build number + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/users/{user}/workspace/{workspacename}/builds/{buildnumber} \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /users/{user}/workspace/{workspacename}/builds/{buildnumber}` + +### Parameters + +| Name | In | Type | Required | Description | +| --------------- | ---- | -------------- | -------- | -------------------- | +| `user` | path | string | true | User ID, name, or me | +| `workspacename` | path | string | true | Workspace name | +| `buildnumber` | path | string(number) | true | Build number | + +### Example responses + +> 200 Response + +```json +{ + "build_number": 0, + "created_at": "2019-08-24T14:15:22Z", + "daily_cost": 0, + "deadline": "2019-08-24T14:15:22Z", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3", + "initiator_name": "string", + "job": { + "canceled_at": "2019-08-24T14:15:22Z", + "completed_at": "2019-08-24T14:15:22Z", + "created_at": "2019-08-24T14:15:22Z", + "error": "string", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" + }, + "reason": "initiator", + "resources": [ + { + "agents": [ + { + "apps": [ + { + "command": "string", + "display_name": "string", + "external": true, + "health": "string", + "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" + } + ], + "created_at": "2019-08-24T14:15:22Z", + "daily_cost": 0, + "hide": true, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f", + "metadata": [ + { + "key": "string", + "sensitive": true, + "value": "string" + } + ], + "name": "string", + "type": "string", + "workspace_transition": "start" + } + ], + "status": "pending", + "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1", + "template_version_name": "string", + "transition": "start", + "updated_at": "2019-08-24T14:15:22Z", + "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9", + "workspace_name": "string", + "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7", + "workspace_owner_name": "string" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ------------------------------------------------------------ | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.WorkspaceBuild](schemas.md#codersdkworkspacebuild) | + +To perform this operation, you must be authenticated. [Learn more](authentication.md). + ## Get workspace build ### Code samples diff --git a/docs/api/users.md b/docs/api/users.md index 71e9ac7e791be..9665d99be9ed7 100644 --- a/docs/api/users.md +++ b/docs/api/users.md @@ -734,6 +734,101 @@ curl -X DELETE http://coder-server:8080/api/v2/users/{user}/keys/{keyid} \ To perform this operation, you must be authenticated. [Learn more](authentication.md). +## Get organizations by user + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/users/{user}/organizations \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /users/{user}/organizations` + +### Parameters + +| Name | In | Type | Required | Description | +| ------ | ---- | ------ | -------- | -------------------- | +| `user` | path | string | true | User ID, name, or me | + +### Example responses + +> 200 Response + +```json +[ + { + "created_at": "2019-08-24T14:15:22Z", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "string", + "updated_at": "2019-08-24T14:15:22Z" + } +] +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ----------------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | array of [codersdk.Organization](schemas.md#codersdkorganization) | + +

Response Schema

+ +Status Code **200** + +| Name | Type | Required | Restrictions | Description | +| -------------- | ----------------- | -------- | ------------ | ----------- | +| `[array item]` | array | false | | | +| `» created_at` | string(date-time) | true | | | +| `» id` | string(uuid) | true | | | +| `» name` | string | true | | | +| `» updated_at` | string(date-time) | true | | | + +To perform this operation, you must be authenticated. [Learn more](authentication.md). + +## Get organization by user and organization name + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/users/{user}/organizations/{organizationname} \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /users/{user}/organizations/{organizationname}` + +### Parameters + +| Name | In | Type | Required | Description | +| ------------------ | ---- | ------ | -------- | -------------------- | +| `user` | path | string | true | User ID, name, or me | +| `organizationname` | path | string | true | Organization name | + +### Example responses + +> 200 Response + +```json +{ + "created_at": "2019-08-24T14:15:22Z", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "string", + "updated_at": "2019-08-24T14:15:22Z" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | -------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.Organization](schemas.md#codersdkorganization) | + +To perform this operation, you must be authenticated. [Learn more](authentication.md). + ## Update user password ### Code samples diff --git a/docs/api/workspaces.md b/docs/api/workspaces.md index 915741e2209ae..1e46376edc726 100644 --- a/docs/api/workspaces.md +++ b/docs/api/workspaces.md @@ -162,7 +162,7 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/member To perform this operation, you must be authenticated. [Learn more](authentication.md). -## Get workspace metadata by owner and workspace name +## Get workspace metadata by user and workspace name ### Code samples @@ -179,7 +179,7 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/workspace/{workspacenam | Name | In | Type | Required | Description | | ----------------- | ----- | ------- | -------- | ----------------------------------------------------------- | -| `user` | path | string | true | Owner username | +| `user` | path | string | true | User ID, name, or me | | `workspacename` | path | string | true | Workspace name | | `include_deleted` | query | boolean | false | Return data instead of HTTP 404 if the workspace is deleted | diff --git a/docs/manifest.json b/docs/manifest.json index 22546066c1dee..a06a5d7bddb58 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -377,14 +377,14 @@ "title": "Authentication", "path": "./api/authentication.md" }, - { - "title": "Agents", - "path": "./api/agents.md" - }, { "title": "Builds", "path": "./api/builds.md" }, + { + "title": "Agents", + "path": "./api/agents.md" + }, { "title": "Schemas", "path": "./api/schemas.md" From ee6dbb198cd2375128fa17657d770429bff7f51b Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Mon, 9 Jan 2023 12:25:33 +0100 Subject: [PATCH 33/36] Typo --- coderd/apikey.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coderd/apikey.go b/coderd/apikey.go index 47ffcd201576e..e4cbd7552c2cc 100644 --- a/coderd/apikey.go +++ b/coderd/apikey.go @@ -125,7 +125,7 @@ func (api *API) postAPIKey(rw http.ResponseWriter, r *http.Request) { } // We intentionally do not set the cookie on the response here. - // Setting the cookie will couple the browser sesion to the API + // Setting the cookie will couple the browser session to the API // key we return here, meaning logging out of the website would // invalid your CLI key. httpapi.Write(ctx, rw, http.StatusCreated, codersdk.GenerateAPIKeyResponse{Key: cookie.Value}) From 8f22f8d3d6f0e4f91cf2f17aefb3af8f22ac8139 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Mon, 9 Jan 2023 12:46:43 +0100 Subject: [PATCH 34/36] Fix --- cli/userstatus_test.go | 6 +++--- coderd/users.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cli/userstatus_test.go b/cli/userstatus_test.go index aea26f8387228..05fe8898c82e6 100644 --- a/cli/userstatus_test.go +++ b/cli/userstatus_test.go @@ -33,7 +33,7 @@ func TestUserStatus(t *testing.T) { }) t.Run("StatusOther", func(t *testing.T) { - require.Equal(t, otherUser.Status, codersdk.UserStatusActive, "start as active") + require.Equal(t, codersdk.UserStatusActive, otherUser.Status, "start as active") cmd, root := clitest.New(t, "users", "suspend", otherUser.Username) clitest.SetupConfig(t, client, root) @@ -45,7 +45,7 @@ func TestUserStatus(t *testing.T) { // Check the user status otherUser, err = client.User(context.Background(), otherUser.Username) require.NoError(t, err, "fetch suspended user") - require.Equal(t, otherUser.Status, codersdk.UserStatusSuspended, "suspended user") + require.Equal(t, codersdk.UserStatusSuspended, otherUser.Status, "suspended user") // Set back to active. Try using a uuid as well cmd, root = clitest.New(t, "users", "activate", otherUser.ID.String()) @@ -58,6 +58,6 @@ func TestUserStatus(t *testing.T) { // Check the user status otherUser, err = client.User(context.Background(), otherUser.ID.String()) require.NoError(t, err, "fetch active user") - require.Equal(t, otherUser.Status, codersdk.UserStatusActive, "active user") + require.Equal(t, codersdk.UserStatusActive, otherUser.Status, "active user") }) } diff --git a/coderd/users.go b/coderd/users.go index 3e6acf34d02c7..759299dc0fc24 100644 --- a/coderd/users.go +++ b/coderd/users.go @@ -542,7 +542,7 @@ func (api *API) putSuspendUserAccount() func(rw http.ResponseWriter, r *http.Req // @Success 200 {object} codersdk.User // @Router /users/{user}/status/activate [put] func (api *API) putActivateUserAccount() func(rw http.ResponseWriter, r *http.Request) { - return api.putUserStatus(database.UserStatusSuspended) + return api.putUserStatus(database.UserStatusActive) } func (api *API) putUserStatus(status database.UserStatus) func(rw http.ResponseWriter, r *http.Request) { From 1f12415b516e841a3afcc9de788996988975f404 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Wed, 11 Jan 2023 12:27:00 +0100 Subject: [PATCH 35/36] Fix --- coderd/apidoc/docs.go | 2 +- coderd/apidoc/swagger.json | 2 +- coderd/users.go | 2 +- docs/api/authentication.md | 50 ++++++-------------------------------- docs/api/authorization.md | 47 +++++++++++++++++++++++++++++++++++ docs/manifest.json | 4 --- 6 files changed, 57 insertions(+), 50 deletions(-) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index aa5e59a0144fd..dde283e999f83 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -2004,7 +2004,7 @@ const docTemplate = `{ "application/json" ], "tags": [ - "Authentication" + "Authorization" ], "summary": "Log in user", "operationId": "log-in-user", diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 022d24348b568..6b6cdece1b4ca 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -1761,7 +1761,7 @@ } ], "produces": ["application/json"], - "tags": ["Authentication"], + "tags": ["Authorization"], "summary": "Log in user", "operationId": "log-in-user", "parameters": [ diff --git a/coderd/users.go b/coderd/users.go index 759299dc0fc24..0485a1e3ec1ed 100644 --- a/coderd/users.go +++ b/coderd/users.go @@ -991,7 +991,7 @@ func (api *API) organizationByUserAndName(rw http.ResponseWriter, r *http.Reques // @ID log-in-user // @Security CoderSessionToken // @Produce json -// @Tags Authentication +// @Tags Authorization // @Param request body codersdk.LoginWithPasswordRequest true "Login request" // @Success 201 {object} codersdk.LoginWithPasswordResponse // @Router /users/login [post] diff --git a/docs/api/authentication.md b/docs/api/authentication.md index c9c37624c7dec..e0bdb045ee139 100644 --- a/docs/api/authentication.md +++ b/docs/api/authentication.md @@ -1,50 +1,14 @@ # Authentication -> This page is incomplete, stay tuned. +Long-lived tokens can be generated to perform actions on behalf of your user account: -## Log in user - -### Code samples - -```shell -# Example request using curl -curl -X POST http://coder-server:8080/api/v2/users/login \ - -H 'Content-Type: application/json' \ - -H 'Accept: application/json' \ - -H 'Coder-Session-Token: API_KEY' -``` - -`POST /users/login` - -> Body parameter - -```json -{ - "email": "string", - "password": "string" -} +```console +coder tokens create ``` -### Parameters +You can use tokens with the Coder's REST API using the `Coder-Session-Token` HTTP header. -| Name | In | Type | Required | Description | -| ------ | ---- | -------------------------------------------------------------------------------- | -------- | ------------- | -| `body` | body | [codersdk.LoginWithPasswordRequest](schemas.md#codersdkloginwithpasswordrequest) | true | Login request | - -### Example responses - -> 201 Response - -```json -{ - "session_token": "string" -} +```console +curl 'http://coder-server:8080/api/v2/workspaces' \ + -H 'Coder-Session-Token: *****' ``` - -### Responses - -| Status | Meaning | Description | Schema | -| ------ | ------------------------------------------------------------ | ----------- | ---------------------------------------------------------------------------------- | -| 201 | [Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) | Created | [codersdk.LoginWithPasswordResponse](schemas.md#codersdkloginwithpasswordresponse) | - -To perform this operation, you must be authenticated. [Learn more](authentication.md). diff --git a/docs/api/authorization.md b/docs/api/authorization.md index 884b3fa3c5c41..f3ea63ab55e24 100644 --- a/docs/api/authorization.md +++ b/docs/api/authorization.md @@ -67,3 +67,50 @@ curl -X POST http://coder-server:8080/api/v2/authcheck \ | 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.AuthorizationResponse](schemas.md#codersdkauthorizationresponse) | To perform this operation, you must be authenticated. [Learn more](authentication.md). + +## Log in user + +### Code samples + +```shell +# Example request using curl +curl -X POST http://coder-server:8080/api/v2/users/login \ + -H 'Content-Type: application/json' \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`POST /users/login` + +> Body parameter + +```json +{ + "email": "string", + "password": "string" +} +``` + +### Parameters + +| Name | In | Type | Required | Description | +| ------ | ---- | -------------------------------------------------------------------------------- | -------- | ------------- | +| `body` | body | [codersdk.LoginWithPasswordRequest](schemas.md#codersdkloginwithpasswordrequest) | true | Login request | + +### Example responses + +> 201 Response + +```json +{ + "session_token": "string" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------------ | ----------- | ---------------------------------------------------------------------------------- | +| 201 | [Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) | Created | [codersdk.LoginWithPasswordResponse](schemas.md#codersdkloginwithpasswordresponse) | + +To perform this operation, you must be authenticated. [Learn more](authentication.md). diff --git a/docs/manifest.json b/docs/manifest.json index a06a5d7bddb58..d0b0d78417b05 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -373,10 +373,6 @@ "title": "Users", "path": "./api/users.md" }, - { - "title": "Authentication", - "path": "./api/authentication.md" - }, { "title": "Builds", "path": "./api/builds.md" From 8773c108ea622b2d36c09ae33d07f3374ddec5c0 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Wed, 11 Jan 2023 13:59:16 +0100 Subject: [PATCH 36/36] Fix: LoginWithPasswordRequest --- coderd/apidoc/docs.go | 3 ++- coderd/apidoc/swagger.json | 3 ++- codersdk/users.go | 2 +- docs/api/authorization.md | 2 +- docs/api/schemas.md | 2 +- 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index dde283e999f83..17fac114fc91b 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -5040,7 +5040,8 @@ const docTemplate = `{ ], "properties": { "email": { - "type": "string" + "type": "string", + "format": "email" }, "password": { "type": "string" diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 6b6cdece1b4ca..1e823c2ef136e 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -4493,7 +4493,8 @@ "required": ["email", "password"], "properties": { "email": { - "type": "string" + "type": "string", + "format": "email" }, "password": { "type": "string" diff --git a/codersdk/users.go b/codersdk/users.go index b6f2926c09a0b..b940b0bc48d9b 100644 --- a/codersdk/users.go +++ b/codersdk/users.go @@ -92,7 +92,7 @@ type UserRoles struct { // LoginWithPasswordRequest enables callers to authenticate with email and password. type LoginWithPasswordRequest struct { - Email string `json:"email" validate:"required,email"` + Email string `json:"email" validate:"required,email" format:"email"` Password string `json:"password" validate:"required"` } diff --git a/docs/api/authorization.md b/docs/api/authorization.md index f3ea63ab55e24..d6f16913e0371 100644 --- a/docs/api/authorization.md +++ b/docs/api/authorization.md @@ -86,7 +86,7 @@ curl -X POST http://coder-server:8080/api/v2/users/login \ ```json { - "email": "string", + "email": "user@example.com", "password": "string" } ``` diff --git a/docs/api/schemas.md b/docs/api/schemas.md index 87dbb943d3e30..edb3d95035093 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -2345,7 +2345,7 @@ CreateParameterRequest is a structure used to create a new parameter value for a ```json { - "email": "string", + "email": "user@example.com", "password": "string" } ```