From 95a7c0c4f087744a22c2e88dd3c5d30024d5fb02 Mon Sep 17 00:00:00 2001 From: Kayla Washburn-Love Date: Thu, 15 Aug 2024 14:53:53 -0600 Subject: [PATCH] chore: use tabs for prettier and biome (#14283) --- .devcontainer/devcontainer.json | 20 +- .github/dependabot.yaml | 4 - .github/workflows/mlc_config.json | 48 +- .prettierrc.yaml | 2 +- .vscode/extensions.json | 26 +- .vscode/settings.json | 468 +- Makefile | 8 +- coderd/apidoc/swagger.json | 28594 ++++++++-------- coderd/rbac/input.json | 88 +- docs/admin/audit-logs.md | 56 +- docs/admin/auth.md | 2 +- docs/contributing/frontend.md | 46 +- docs/guides/gcp-to-aws.md | 118 +- docs/guides/image-pull-secret.md | 26 +- docs/manifest.json | 2364 +- docs/reference/api/agents.md | 426 +- docs/reference/api/applications.md | 2 +- docs/reference/api/audit.md | 120 +- docs/reference/api/authorization.md | 66 +- docs/reference/api/builds.md | 1742 +- docs/reference/api/debug.md | 658 +- docs/reference/api/enterprise.md | 1294 +- docs/reference/api/files.md | 2 +- docs/reference/api/general.md | 838 +- docs/reference/api/git.md | 74 +- docs/reference/api/insights.md | 174 +- docs/reference/api/members.md | 454 +- docs/reference/api/notifications.md | 62 +- docs/reference/api/organizations.md | 126 +- docs/reference/api/portsharing.md | 22 +- docs/reference/api/schemas.md | 8758 ++--- docs/reference/api/templates.md | 1902 +- docs/reference/api/users.md | 602 +- docs/reference/api/workspaceproxies.md | 22 +- docs/reference/api/workspaces.md | 2208 +- docs/templates/process-logging.md | 44 +- dogfood/devcontainer.json | 12 +- dogfood/files/etc/docker/daemon.json | 2 +- examples/examples.gen.json | 332 +- .../dashboards/grafana/dashboard.json | 2006 +- examples/templates/aws-devcontainer/README.md | 88 +- examples/templates/aws-linux/README.md | 88 +- examples/templates/aws-windows/README.md | 88 +- offlinedocs/.eslintrc.json | 2 +- offlinedocs/next.config.js | 6 +- offlinedocs/package.json | 86 +- offlinedocs/pages/[[...slug]].tsx | 838 +- offlinedocs/pages/_app.tsx | 36 +- offlinedocs/tsconfig.json | 36 +- package.json | 24 +- scaletest/scaletest_dashboard.json | 10114 +++--- scripts/apidocgen/package.json | 14 +- scripts/apitypings/main.go | 2 +- .../testdata/genericmap/genericmap.ts | 8 +- .../apitypings/testdata/generics/generics.ts | 28 +- .../testdata/genericslice/genericslice.ts | 6 +- scripts/examplegen/main.go | 2 +- site/biome.json | 82 +- site/e2e/api.ts | 244 +- site/e2e/constants.ts | 30 +- site/e2e/expectUrl.ts | 60 +- site/e2e/global.setup.ts | 60 +- site/e2e/helpers.ts | 1412 +- site/e2e/hooks.ts | 136 +- site/e2e/parameters.ts | 214 +- site/e2e/playwright.config.ts | 254 +- site/e2e/provisionerGenerated.ts | 1694 +- site/e2e/proxy.ts | 56 +- site/e2e/reporter.ts | 270 +- site/e2e/tests/app.spec.ts | 106 +- site/e2e/tests/auditLogs.spec.ts | 104 +- site/e2e/tests/deployment/appearance.spec.ts | 106 +- site/e2e/tests/deployment/general.spec.ts | 54 +- site/e2e/tests/deployment/licenses.spec.ts | 40 +- site/e2e/tests/deployment/network.spec.ts | 62 +- .../tests/deployment/observability.spec.ts | 60 +- site/e2e/tests/deployment/security.spec.ts | 60 +- site/e2e/tests/deployment/userAuth.spec.ts | 48 +- .../tests/deployment/workspaceProxies.spec.ts | 148 +- site/e2e/tests/externalAuth.spec.ts | 262 +- site/e2e/tests/groups/addMembers.spec.ts | 44 +- .../groups/addUsersToDefaultGroup.spec.ts | 34 +- site/e2e/tests/groups/createGroup.spec.ts | 36 +- .../tests/groups/navigateToGroupPage.spec.ts | 22 +- site/e2e/tests/groups/removeGroup.spec.ts | 28 +- site/e2e/tests/groups/removeMember.spec.ts | 42 +- site/e2e/tests/organizations.spec.ts | 40 +- site/e2e/tests/outdatedAgent.spec.ts | 96 +- site/e2e/tests/outdatedCLI.spec.ts | 94 +- .../e2e/tests/templates/listTemplates.spec.ts | 4 +- .../templates/updateTemplateSchedule.spec.ts | 66 +- site/e2e/tests/updateTemplate.spec.ts | 94 +- .../users/createUserWithPassword.spec.ts | 96 +- site/e2e/tests/users/removeUser.spec.ts | 26 +- site/e2e/tests/webTerminal.spec.ts | 112 +- .../workspaces/autoCreateWorkspace.spec.ts | 98 +- .../tests/workspaces/createWorkspace.spec.ts | 302 +- .../tests/workspaces/restartWorkspace.spec.ts | 66 +- .../tests/workspaces/startWorkspace.spec.ts | 70 +- .../tests/workspaces/updateWorkspace.spec.ts | 196 +- site/src/@types/emoji-mart.d.ts | 70 +- site/src/@types/emotion.d.ts | 2 +- site/src/@types/mui.d.ts | 34 +- site/src/@types/storybook.d.ts | 36 +- site/src/App.tsx | 114 +- site/src/__mocks__/monaco-editor.ts | 22 +- site/src/__mocks__/react-markdown.tsx | 2 +- site/src/api/api.test.ts | 400 +- site/src/api/api.ts | 4000 +-- site/src/api/errors.test.ts | 170 +- site/src/api/errors.ts | 154 +- site/src/api/queries/appearance.ts | 22 +- site/src/api/queries/audits.ts | 32 +- site/src/api/queries/authCheck.ts | 10 +- site/src/api/queries/buildInfo.ts | 12 +- site/src/api/queries/debug.ts | 50 +- site/src/api/queries/deployment.ts | 32 +- site/src/api/queries/entitlements.ts | 26 +- site/src/api/queries/experiments.ts | 18 +- site/src/api/queries/externalAuth.ts | 78 +- site/src/api/queries/files.ts | 14 +- site/src/api/queries/groups.ts | 226 +- site/src/api/queries/insights.ts | 24 +- site/src/api/queries/integrations.ts | 8 +- site/src/api/queries/notifications.ts | 202 +- site/src/api/queries/oauth2.ts | 140 +- site/src/api/queries/organizations.ts | 364 +- site/src/api/queries/roles.ts | 84 +- site/src/api/queries/settings.ts | 38 +- site/src/api/queries/sshKeys.ts | 24 +- site/src/api/queries/templates.ts | 438 +- site/src/api/queries/updateCheck.ts | 8 +- site/src/api/queries/users.ts | 348 +- site/src/api/queries/util.ts | 92 +- site/src/api/queries/workspaceBuilds.ts | 72 +- site/src/api/queries/workspaceQuota.ts | 24 +- site/src/api/queries/workspaceportsharing.ts | 32 +- site/src/api/queries/workspaces.ts | 582 +- ...urces_gen.ts => rbacresourcesGenerated.ts} | 0 site/src/api/typesGenerated.ts | 2314 +- site/src/components/Abbr/Abbr.stories.tsx | 110 +- site/src/components/Abbr/Abbr.test.tsx | 152 +- site/src/components/Abbr/Abbr.tsx | 70 +- .../ActiveUserChart.stories.tsx | 34 +- .../ActiveUserChart/ActiveUserChart.tsx | 270 +- site/src/components/Alert/Alert.stories.tsx | 58 +- site/src/components/Alert/Alert.tsx | 122 +- .../components/Alert/ErrorAlert.stories.tsx | 58 +- site/src/components/Alert/ErrorAlert.tsx | 36 +- site/src/components/Avatar/Avatar.stories.tsx | 58 +- site/src/components/Avatar/Avatar.tsx | 150 +- .../AvatarCard/AvatarCard.stories.tsx | 30 +- site/src/components/AvatarCard/AvatarCard.tsx | 132 +- .../AvatarData/AvatarData.stories.tsx | 18 +- site/src/components/AvatarData/AvatarData.tsx | 106 +- .../AvatarData/AvatarDataSkeleton.tsx | 18 +- site/src/components/Badges/Badges.stories.tsx | 86 +- site/src/components/Badges/Badges.tsx | 308 +- .../BuildAvatar/BuildAvatar.stories.tsx | 178 +- .../components/BuildAvatar/BuildAvatar.tsx | 62 +- .../BuildIcon/BuildIcon.stories.tsx | 22 +- site/src/components/BuildIcon/BuildIcon.tsx | 12 +- .../CodeExample/CodeExample.stories.tsx | 32 +- .../components/CodeExample/CodeExample.tsx | 164 +- .../Conditionals/ChooseOne.stories.tsx | 98 +- .../src/components/Conditionals/ChooseOne.tsx | 50 +- .../CopyButton/CopyButton.stories.tsx | 12 +- site/src/components/CopyButton/CopyButton.tsx | 86 +- .../CopyableValue/CopyableValue.stories.tsx | 12 +- .../CopyableValue/CopyableValue.tsx | 46 +- .../ConfirmDialog/ConfirmDialog.stories.tsx | 78 +- .../ConfirmDialog/ConfirmDialog.test.tsx | 72 +- .../Dialogs/ConfirmDialog/ConfirmDialog.tsx | 224 +- .../DeleteDialog/DeleteDialog.stories.tsx | 26 +- .../DeleteDialog/DeleteDialog.test.tsx | 106 +- .../Dialogs/DeleteDialog/DeleteDialog.tsx | 190 +- site/src/components/Dialogs/Dialog.tsx | 248 +- .../DropdownArrow/DropdownArrow.stories.tsx | 8 +- .../DropdownArrow/DropdownArrow.tsx | 44 +- .../DurationField/DurationField.stories.tsx | 110 +- .../DurationField/DurationField.tsx | 274 +- .../EmptyState/EmptyState.stories.tsx | 18 +- site/src/components/EmptyState/EmptyState.tsx | 88 +- .../ErrorBoundary/ErrorBoundary.tsx | 40 +- .../RuntimeErrorState.stories.tsx | 24 +- .../ErrorBoundary/RuntimeErrorState.tsx | 298 +- .../components/Expander/Expander.stories.tsx | 16 +- site/src/components/Expander/Expander.tsx | 92 +- .../ExternalImage/ExternalImage.tsx | 22 +- .../FileUpload/FileUpload.stories.tsx | 36 +- .../components/FileUpload/FileUpload.test.tsx | 60 +- site/src/components/FileUpload/FileUpload.tsx | 284 +- .../Filter/SelectFilter.stories.tsx | 204 +- site/src/components/Filter/SelectFilter.tsx | 196 +- site/src/components/Filter/UserFilter.tsx | 200 +- site/src/components/Filter/filter.tsx | 506 +- site/src/components/Filter/menu.ts | 162 +- site/src/components/Filter/storyHelpers.ts | 48 +- site/src/components/Form/Form.stories.tsx | 42 +- site/src/components/Form/Form.tsx | 328 +- .../FormFooter/FormFooter.stories.tsx | 32 +- site/src/components/FormFooter/FormFooter.tsx | 116 +- .../FullPageForm/FullPageForm.stories.tsx | 38 +- .../components/FullPageForm/FullPageForm.tsx | 36 +- .../FullPageForm/FullPageHorizontalForm.tsx | 56 +- .../src/components/FullPageLayout/Sidebar.tsx | 182 +- site/src/components/FullPageLayout/Topbar.tsx | 188 +- .../EnterpriseSnackbar.stories.tsx | 34 +- .../GlobalSnackbar/EnterpriseSnackbar.tsx | 114 +- .../GlobalSnackbar/GlobalSnackbar.tsx | 164 +- .../components/GlobalSnackbar/utils.test.ts | 210 +- site/src/components/GlobalSnackbar/utils.ts | 72 +- .../GroupAvatar/GroupAvatar.stories.tsx | 12 +- .../components/GroupAvatar/GroupAvatar.tsx | 60 +- .../HelpTooltip/HelpTooltip.stories.tsx | 50 +- .../components/HelpTooltip/HelpTooltip.tsx | 314 +- site/src/components/IconField/EmojiPicker.tsx | 48 +- .../IconField/IconField.stories.tsx | 22 +- site/src/components/IconField/IconField.tsx | 176 +- site/src/components/Icons/CoderIcon.tsx | 16 +- site/src/components/Icons/DockerIcon.tsx | 36 +- site/src/components/Icons/EditSquare.tsx | 6 +- site/src/components/Icons/ErrorIcon.tsx | 16 +- site/src/components/Icons/FileCopyIcon.tsx | 12 +- site/src/components/Icons/GitIcon.tsx | 6 +- site/src/components/Icons/GitlabIcon.tsx | 50 +- site/src/components/Icons/JetBrainsIcon.tsx | 90 +- site/src/components/Icons/MarkdownIcon.tsx | 34 +- site/src/components/Icons/RocketIcon.tsx | 6 +- site/src/components/Icons/TerminalIcon.tsx | 6 +- site/src/components/Icons/TerraformIcon.tsx | 36 +- site/src/components/Icons/VSCodeIcon.tsx | 260 +- .../components/Icons/VSCodeInsidersIcon.tsx | 244 +- .../InfoTooltip/InfoTooltip.stories.tsx | 84 +- .../components/InfoTooltip/InfoTooltip.tsx | 52 +- .../InputGroup/InputGroup.stories.tsx | 108 +- site/src/components/InputGroup/InputGroup.tsx | 90 +- .../components/LastSeen/LastSeen.stories.tsx | 54 +- site/src/components/LastSeen/LastSeen.tsx | 54 +- .../components/Latency/Latency.stories.tsx | 28 +- site/src/components/Latency/Latency.tsx | 80 +- site/src/components/Loader/Loader.stories.tsx | 10 +- site/src/components/Loader/Loader.tsx | 64 +- site/src/components/Logs/LogLine.stories.tsx | 48 +- site/src/components/Logs/LogLine.tsx | 104 +- site/src/components/Logs/Logs.stories.tsx | 22 +- site/src/components/Logs/Logs.tsx | 66 +- .../components/Margins/Margins.stories.tsx | 18 +- site/src/components/Margins/Margins.tsx | 52 +- .../components/Markdown/Markdown.stories.tsx | 16 +- site/src/components/Markdown/Markdown.tsx | 378 +- site/src/components/Menu/MenuSearch.tsx | 34 +- .../components/MoreMenu/MoreMenu.stories.tsx | 80 +- site/src/components/MoreMenu/MoreMenu.tsx | 182 +- .../OrganizationAutocomplete.tsx | 264 +- .../OverflowY/OverflowY.stories.tsx | 40 +- site/src/components/OverflowY/OverflowY.tsx | 58 +- .../PageHeader/FullWidthPageHeader.tsx | 146 +- .../PageHeader/PageHeader.stories.tsx | 30 +- site/src/components/PageHeader/PageHeader.tsx | 194 +- .../PaginationWidget/PageButtons.tsx | 164 +- .../PaginationContainer.mocks.ts | 50 +- .../PaginationContainer.stories.tsx | 174 +- .../PaginationWidget/PaginationContainer.tsx | 74 +- .../PaginationWidget/PaginationHeader.tsx | 108 +- .../PaginationWidget/PaginationNavButton.tsx | 162 +- .../PaginationWidgetBase.stories.tsx | 22 +- .../PaginationWidgetBase.test.tsx | 128 +- .../PaginationWidget/PaginationWidgetBase.tsx | 208 +- .../components/PaginationWidget/utils.test.ts | 194 +- site/src/components/PaginationWidget/utils.ts | 68 +- .../components/Paywall/Paywall.stories.tsx | 14 +- site/src/components/Paywall/Paywall.tsx | 208 +- .../Paywall/PopoverPaywall.stories.tsx | 26 +- .../src/components/Paywall/PopoverPaywall.tsx | 220 +- site/src/components/Pill/Pill.stories.tsx | 88 +- site/src/components/Pill/Pill.tsx | 122 +- .../components/Popover/Popover.stories.tsx | 68 +- site/src/components/Popover/Popover.tsx | 272 +- .../RichParameterInput/MultiTextField.tsx | 168 +- .../RichParameterInput.stories.tsx | 506 +- .../RichParameterInput/RichParameterInput.tsx | 666 +- site/src/components/Search/Search.stories.tsx | 26 +- site/src/components/Search/Search.tsx | 138 +- .../SearchField/SearchField.stories.tsx | 48 +- .../components/SearchField/SearchField.tsx | 84 +- .../SelectMenu/SelectMenu.stories.tsx | 206 +- site/src/components/SelectMenu/SelectMenu.tsx | 236 +- .../SettingsHeader/SettingsHeader.tsx | 112 +- .../components/Sidebar/Sidebar.stories.tsx | 56 +- site/src/components/Sidebar/Sidebar.tsx | 150 +- .../components/SignInLayout/SignInLayout.tsx | 66 +- site/src/components/Stack/Stack.stories.tsx | 56 +- site/src/components/Stack/Stack.tsx | 64 +- site/src/components/StackLabel/StackLabel.tsx | 38 +- site/src/components/Stats/Stats.tsx | 122 +- .../StatusIndicator/StatusIndicator.tsx | 24 +- .../SyntaxHighlighter/SyntaxHighlighter.tsx | 88 +- .../SyntaxHighlighter/coderTheme.ts | 28 +- .../TableEmpty/TableEmpty.stories.tsx | 80 +- site/src/components/TableEmpty/TableEmpty.tsx | 18 +- .../TableLoader/TableLoader.stories.tsx | 26 +- .../components/TableLoader/TableLoader.tsx | 60 +- .../TableToolbar/TableToolbar.stories.tsx | 30 +- .../components/TableToolbar/TableToolbar.tsx | 80 +- site/src/components/Tabs/Tabs.stories.tsx | 36 +- site/src/components/Tabs/Tabs.tsx | 118 +- .../TemplateAvatar/TemplateAvatar.tsx | 16 +- site/src/components/Timeline/Timeline.tsx | 64 +- .../components/Timeline/TimelineDateRow.tsx | 42 +- .../src/components/Timeline/TimelineEntry.tsx | 80 +- site/src/components/Timeline/utils.test.ts | 20 +- site/src/components/Timeline/utils.ts | 14 +- .../UserAutocomplete.stories.tsx | 18 +- .../UserAutocomplete/UserAutocomplete.tsx | 226 +- .../UserAvatar/UserAvatar.stories.tsx | 20 +- site/src/components/UserAvatar/UserAvatar.tsx | 20 +- .../components/Welcome/Welcome.stories.tsx | 4 +- site/src/components/Welcome/Welcome.tsx | 66 +- site/src/contexts/ProxyContext.test.tsx | 666 +- site/src/contexts/ProxyContext.tsx | 452 +- site/src/contexts/ThemeProvider.tsx | 116 +- site/src/contexts/auth/AuthProvider.test.tsx | 38 +- site/src/contexts/auth/AuthProvider.tsx | 204 +- site/src/contexts/auth/RequireAuth.test.tsx | 148 +- site/src/contexts/auth/RequireAuth.tsx | 116 +- site/src/contexts/auth/RequirePermission.tsx | 16 +- site/src/contexts/auth/permissions.tsx | 260 +- site/src/contexts/useProxyLatency.ts | 480 +- site/src/hooks/debounce.test.ts | 236 +- site/src/hooks/debounce.ts | 96 +- site/src/hooks/events.test.ts | 18 +- site/src/hooks/events.ts | 22 +- site/src/hooks/hookPolyfills.test.ts | 58 +- site/src/hooks/hookPolyfills.ts | 24 +- site/src/hooks/useClassName.ts | 12 +- site/src/hooks/useClickable.test.tsx | 228 +- site/src/hooks/useClickable.ts | 88 +- site/src/hooks/useClickableTableRow.ts | 98 +- site/src/hooks/useClipboard.test.tsx | 368 +- site/src/hooks/useClipboard.ts | 208 +- site/src/hooks/useEmbeddedMetadata.test.ts | 400 +- site/src/hooks/useEmbeddedMetadata.ts | 330 +- site/src/hooks/usePaginatedQuery.test.ts | 640 +- site/src/hooks/usePaginatedQuery.ts | 608 +- site/src/hooks/usePagination.ts | 32 +- site/src/hooks/useSearchParamsKey.test.ts | 194 +- site/src/hooks/useSearchParamsKey.ts | 56 +- site/src/hooks/useTime.ts | 48 +- site/src/hooks/useWindowSize.ts | 34 +- site/src/hooks/useWorkspaceBuildLogs.ts | 64 +- site/src/index.tsx | 34 +- .../AnnouncementBannerView.stories.tsx | 20 +- .../AnnouncementBannerView.tsx | 46 +- .../AnnouncementBanners.tsx | 40 +- .../dashboard/DashboardLayout.test.tsx | 26 +- .../src/modules/dashboard/DashboardLayout.tsx | 186 +- .../modules/dashboard/DashboardProvider.tsx | 96 +- .../DeploymentBanner/DeploymentBanner.tsx | 32 +- .../DeploymentBannerView.stories.tsx | 38 +- .../DeploymentBanner/DeploymentBannerView.tsx | 666 +- .../dashboard/LicenseBanner/LicenseBanner.tsx | 12 +- .../LicenseBannerView.stories.tsx | 40 +- .../LicenseBanner/LicenseBannerView.tsx | 142 +- .../dashboard/Navbar/DeploymentDropdown.tsx | 254 +- .../modules/dashboard/Navbar/Navbar.test.tsx | 112 +- site/src/modules/dashboard/Navbar/Navbar.tsx | 58 +- .../dashboard/Navbar/NavbarView.stories.tsx | 114 +- .../dashboard/Navbar/NavbarView.test.tsx | 204 +- .../modules/dashboard/Navbar/NavbarView.tsx | 284 +- .../dashboard/Navbar/ProxyMenu.stories.tsx | 102 +- .../modules/dashboard/Navbar/ProxyMenu.tsx | 428 +- .../UserDropdown/UserDropdown.stories.tsx | 46 +- .../Navbar/UserDropdown/UserDropdown.tsx | 126 +- .../UserDropdown/UserDropdownContent.test.tsx | 48 +- .../UserDropdown/UserDropdownContent.tsx | 302 +- .../modules/dashboard/entitlements.test.ts | 60 +- site/src/modules/dashboard/entitlements.ts | 28 +- site/src/modules/dashboard/useDashboard.ts | 14 +- .../modules/dashboard/useFeatureVisibility.ts | 4 +- .../modules/dashboard/useUpdateCheck.test.tsx | 150 +- site/src/modules/dashboard/useUpdateCheck.ts | 58 +- site/src/modules/navigation.ts | 22 +- site/src/modules/notifications/utils.tsx | 24 +- site/src/modules/resources/AgentButton.tsx | 48 +- site/src/modules/resources/AgentLatency.tsx | 132 +- .../resources/AgentLogs/AgentLogLine.tsx | 78 +- .../resources/AgentLogs/AgentLogs.stories.tsx | 20 +- .../modules/resources/AgentLogs/AgentLogs.tsx | 354 +- .../src/modules/resources/AgentLogs/mocks.tsx | 2244 +- .../resources/AgentLogs/useAgentLogs.test.tsx | 232 +- .../resources/AgentLogs/useAgentLogs.ts | 118 +- .../resources/AgentMetadata.stories.tsx | 176 +- site/src/modules/resources/AgentMetadata.tsx | 394 +- .../resources/AgentOutdatedTooltip.tsx | 124 +- .../modules/resources/AgentRow.stories.tsx | 486 +- site/src/modules/resources/AgentRow.test.tsx | 180 +- site/src/modules/resources/AgentRow.tsx | 846 +- .../resources/AgentRowPreview.stories.tsx | 52 +- .../resources/AgentRowPreview.test.tsx | 212 +- .../src/modules/resources/AgentRowPreview.tsx | 364 +- site/src/modules/resources/AgentStatus.tsx | 504 +- site/src/modules/resources/AgentVersion.tsx | 50 +- .../resources/AppLink/AppLink.stories.tsx | 248 +- .../src/modules/resources/AppLink/AppLink.tsx | 260 +- .../modules/resources/AppLink/AppPreview.tsx | 44 +- .../modules/resources/AppLink/BaseIcon.tsx | 20 +- .../modules/resources/AppLink/ShareIcon.tsx | 46 +- .../DownloadAgentLogsButton.stories.tsx | 76 +- .../resources/DownloadAgentLogsButton.tsx | 92 +- .../resources/PortForwardButton.stories.tsx | 44 +- .../modules/resources/PortForwardButton.tsx | 1206 +- .../PortForwardPopoverView.stories.tsx | 204 +- .../resources/PortForwardPopoverView.test.tsx | 56 +- .../resources/ResourceAvatar.stories.tsx | 78 +- site/src/modules/resources/ResourceAvatar.tsx | 28 +- .../resources/ResourceCard.stories.tsx | 152 +- .../modules/resources/ResourceCard.test.tsx | 198 +- site/src/modules/resources/ResourceCard.tsx | 284 +- .../modules/resources/Resources.stories.tsx | 306 +- site/src/modules/resources/Resources.tsx | 102 +- .../resources/SSHButton/SSHButton.stories.tsx | 36 +- .../modules/resources/SSHButton/SSHButton.tsx | 148 +- site/src/modules/resources/SensitiveValue.tsx | 88 +- .../TerminalLink/TerminalLink.stories.tsx | 10 +- .../resources/TerminalLink/TerminalLink.tsx | 62 +- .../VSCodeDesktopButton.stories.tsx | 28 +- .../VSCodeDesktopButton.tsx | 314 +- site/src/modules/resources/XRayScanAlert.tsx | 194 +- .../TemplateExampleCard.stories.tsx | 34 +- .../TemplateExampleCard.tsx | 208 +- .../TemplateFileTree.stories.tsx | 122 +- .../TemplateFiles/TemplateFileTree.tsx | 424 +- .../TemplateFiles/TemplateFiles.stories.tsx | 42 +- .../templates/TemplateFiles/TemplateFiles.tsx | 338 +- .../templates/TemplateFiles/isBinaryData.ts | 34 +- .../TemplateResourcesTable.stories.tsx | 44 +- .../TemplateResourcesTable.tsx | 24 +- .../TemplateUpdateMessage.stories.tsx | 10 +- .../templates/TemplateUpdateMessage.tsx | 60 +- .../modules/templates/useWatchVersionLogs.ts | 60 +- .../WorkspaceBuildData.stories.tsx | 130 +- .../WorkspaceBuildData/WorkspaceBuildData.tsx | 122 +- .../WorkspaceBuildLogs.stories.tsx | 18 +- .../WorkspaceBuildLogs/WorkspaceBuildLogs.tsx | 184 +- .../WorkspaceDormantBadge.stories.tsx | 46 +- .../WorkspaceDormantBadge.tsx | 86 +- .../WorkspaceOutdatedTooltip.stories.tsx | 54 +- .../WorkspaceOutdatedTooltip.tsx | 202 +- .../WorkspaceStatusBadge.stories.tsx | 104 +- .../WorkspaceStatusBadge.tsx | 124 +- site/src/modules/workspaces/activity.ts | 64 +- .../workspaces/generateWorkspaceName.ts | 22 +- site/src/pages/404Page/404Page.stories.tsx | 4 +- site/src/pages/404Page/404Page.tsx | 46 +- site/src/pages/AuditPage/AuditFilter.tsx | 428 +- site/src/pages/AuditPage/AuditHelpTooltip.tsx | 48 +- .../AuditLogDescription.stories.tsx | 126 +- .../AuditLogDescription.tsx | 82 +- .../BuildAuditDescription.tsx | 66 +- .../AuditLogRow/AuditLogDiff/AuditLogDiff.tsx | 194 +- .../AuditLogDiff/auditUtils.test.ts | 200 +- .../AuditLogRow/AuditLogDiff/auditUtils.ts | 28 +- .../AuditLogRow/AuditLogRow.stories.tsx | 214 +- .../AuditPage/AuditLogRow/AuditLogRow.tsx | 472 +- site/src/pages/AuditPage/AuditPage.test.tsx | 162 +- site/src/pages/AuditPage/AuditPage.tsx | 156 +- .../pages/AuditPage/AuditPageView.stories.tsx | 138 +- site/src/pages/AuditPage/AuditPageView.tsx | 214 +- site/src/pages/CliAuthPage/CliAuthPage.tsx | 18 +- .../CliAuthPage/CliAuthPageView.stories.tsx | 10 +- .../src/pages/CliAuthPage/CliAuthPageView.tsx | 94 +- .../BuildLogsDrawer.stories.tsx | 68 +- .../CreateTemplatePage/BuildLogsDrawer.tsx | 288 +- .../CreateTemplateForm.stories.tsx | 254 +- .../CreateTemplatePage/CreateTemplateForm.tsx | 666 +- .../CreateTemplatePage.test.tsx | 262 +- .../CreateTemplatePage/CreateTemplatePage.tsx | 100 +- .../DuplicateTemplateView.tsx | 136 +- .../ImportStarterTemplateView.tsx | 136 +- .../CreateTemplatePage/TemplateUpload.tsx | 72 +- .../CreateTemplatePage/UploadTemplateView.tsx | 116 +- .../CreateTemplatePage/VariableInput.tsx | 198 +- site/src/pages/CreateTemplatePage/types.ts | 10 +- site/src/pages/CreateTemplatePage/utils.ts | 118 +- .../CreateTemplatesGalleryPage.tsx | 52 +- .../CreateTemplatesPageView.tsx | 240 +- .../StarterTemplates.tsx | 170 +- .../StarterTemplatesPage.test.tsx | 78 +- .../StarterTemplatesPageView.stories.tsx | 38 +- .../StarterTemplatesPageView.tsx | 40 +- .../pages/CreateTokenPage/CreateTokenForm.tsx | 254 +- .../CreateTokenPage.stories.tsx | 32 +- .../CreateTokenPage/CreateTokenPage.test.tsx | 40 +- .../pages/CreateTokenPage/CreateTokenPage.tsx | 184 +- site/src/pages/CreateTokenPage/utils.test.tsx | 132 +- site/src/pages/CreateTokenPage/utils.ts | 88 +- .../CreateUserPage/CreateUserForm.stories.tsx | 40 +- .../pages/CreateUserPage/CreateUserForm.tsx | 362 +- .../CreateUserPage/CreateUserPage.test.tsx | 68 +- .../pages/CreateUserPage/CreateUserPage.tsx | 50 +- .../CreateWorkspacePage.test.tsx | 592 +- .../CreateWorkspacePage.tsx | 500 +- .../CreateWorkspacePageView.stories.tsx | 356 +- .../CreateWorkspacePageView.tsx | 544 +- .../ExternalAuthButton.stories.tsx | 156 +- .../ExternalAuthButton.tsx | 136 +- .../SelectedTemplate.stories.tsx | 28 +- .../CreateWorkspacePage/SelectedTemplate.tsx | 80 +- .../pages/CreateWorkspacePage/permissions.ts | 24 +- .../useWorkspaceDuplication.test.tsx | 150 +- .../useWorkspaceDuplication.ts | 94 +- .../AnnouncementBannerDialog.stories.tsx | 22 +- .../AnnouncementBannerDialog.tsx | 226 +- .../AnnouncementBannerItem.tsx | 110 +- .../AnnouncementBannerSettings.tsx | 336 +- .../AppearanceSettingsPage.tsx | 62 +- .../AppearanceSettingsPageView.stories.tsx | 48 +- .../AppearanceSettingsPageView.tsx | 260 +- .../DeploySettingsLayout.tsx | 76 +- .../ExternalAuthSettingsPage.tsx | 26 +- .../ExternalAuthSettingsPageView.stories.tsx | 50 +- .../ExternalAuthSettingsPageView.tsx | 136 +- .../src/pages/DeploySettingsPage/Fieldset.tsx | 142 +- .../GeneralSettingsPage/ChartSection.tsx | 92 +- .../GeneralSettingsPage.tsx | 60 +- .../GeneralSettingsPageView.stories.tsx | 236 +- .../GeneralSettingsPageView.tsx | 156 +- .../AddNewLicensePage.tsx | 72 +- .../AddNewLicensePageView.stories.tsx | 12 +- .../AddNewLicensePageView.tsx | 152 +- .../LicensesSettingsPage/DividerWithText.tsx | 46 +- .../LicensesSettingsPage/LicenseCard.test.tsx | 114 +- .../LicensesSettingsPage/LicenseCard.tsx | 280 +- .../LicensesSettingsPage.tsx | 142 +- .../LicensesSettingsPageView.stories.tsx | 26 +- .../LicensesSettingsPageView.tsx | 234 +- .../NetworkSettingsPage.tsx | 26 +- .../NetworkSettingsPageView.stories.tsx | 112 +- .../NetworkSettingsPageView.tsx | 68 +- .../NotificationsPage.stories.tsx | 488 +- .../NotificationsPage/NotificationsPage.tsx | 472 +- .../CreateOAuth2AppPage.tsx | 50 +- .../CreateOAuth2AppPageView.stories.tsx | 54 +- .../CreateOAuth2AppPageView.tsx | 70 +- .../EditOAuth2AppPage.tsx | 174 +- .../EditOAuth2AppPageView.stories.tsx | 122 +- .../EditOAuth2AppPageView.tsx | 526 +- .../OAuth2AppsSettingsPage/OAuth2AppForm.tsx | 144 +- .../OAuth2AppsSettingsPage.tsx | 26 +- .../OAuth2AppsSettingsPageView.stories.tsx | 32 +- .../OAuth2AppsSettingsPageView.tsx | 172 +- .../ObservabilitySettingsPage.tsx | 34 +- .../ObservabilitySettingsPageView.stories.tsx | 80 +- .../ObservabilitySettingsPageView.tsx | 76 +- site/src/pages/DeploySettingsPage/Option.tsx | 290 +- .../pages/DeploySettingsPage/OptionsTable.tsx | 162 +- .../SecuritySettingsPage.tsx | 34 +- .../SecuritySettingsPageView.stories.tsx | 118 +- .../SecuritySettingsPageView.tsx | 106 +- site/src/pages/DeploySettingsPage/Sidebar.tsx | 80 +- .../UserAuthSettingsPage.tsx | 26 +- .../UserAuthSettingsPageView.stories.tsx | 208 +- .../UserAuthSettingsPageView.tsx | 102 +- .../DeploySettingsPage/optionValue.test.ts | 278 +- .../pages/DeploySettingsPage/optionValue.ts | 110 +- .../ExternalAuthPage/ExternalAuthPage.tsx | 182 +- .../ExternalAuthPageView.stories.tsx | 226 +- .../ExternalAuthPage/ExternalAuthPageView.tsx | 444 +- site/src/pages/GroupsPage/CreateGroupPage.tsx | 36 +- .../CreateGroupPageView.stories.tsx | 18 +- .../pages/GroupsPage/CreateGroupPageView.tsx | 116 +- site/src/pages/GroupsPage/GroupPage.tsx | 572 +- site/src/pages/GroupsPage/GroupsPage.tsx | 44 +- .../GroupsPage/GroupsPageView.stories.tsx | 54 +- site/src/pages/GroupsPage/GroupsPageView.tsx | 326 +- .../pages/GroupsPage/SettingsGroupPage.tsx | 100 +- .../SettingsGroupPageView.stories.tsx | 14 +- .../GroupsPage/SettingsGroupPageView.tsx | 216 +- .../HealthPage/AccessURLPage.stories.tsx | 44 +- site/src/pages/HealthPage/AccessURLPage.tsx | 96 +- site/src/pages/HealthPage/Content.tsx | 378 +- .../src/pages/HealthPage/DERPPage.stories.tsx | 10 +- site/src/pages/HealthPage/DERPPage.tsx | 216 +- .../HealthPage/DERPRegionPage.stories.tsx | 14 +- site/src/pages/HealthPage/DERPRegionPage.tsx | 378 +- .../pages/HealthPage/DatabasePage.stories.tsx | 10 +- site/src/pages/HealthPage/DatabasePage.tsx | 90 +- .../pages/HealthPage/DismissWarningButton.tsx | 118 +- site/src/pages/HealthPage/HealthLayout.tsx | 414 +- .../ProvisionerDaemonsPage.stories.tsx | 10 +- .../HealthPage/ProvisionerDaemonsPage.tsx | 390 +- .../HealthPage/WebsocketPage.stories.tsx | 44 +- site/src/pages/HealthPage/WebsocketPage.tsx | 118 +- .../HealthPage/WorkspaceProxyPage.stories.tsx | 44 +- .../pages/HealthPage/WorkspaceProxyPage.tsx | 310 +- site/src/pages/HealthPage/healthyColor.ts | 16 +- site/src/pages/HealthPage/storybook.tsx | 64 +- .../src/pages/IconsPage/IconsPage.stories.tsx | 8 +- site/src/pages/IconsPage/IconsPage.tsx | 336 +- site/src/pages/LoginPage/LoginPage.test.tsx | 122 +- site/src/pages/LoginPage/LoginPage.tsx | 166 +- .../pages/LoginPage/LoginPageView.stories.tsx | 86 +- site/src/pages/LoginPage/LoginPageView.tsx | 204 +- site/src/pages/LoginPage/OAuthSignInForm.tsx | 128 +- .../pages/LoginPage/PasswordSignInForm.tsx | 108 +- .../pages/LoginPage/SignInForm.stories.tsx | 118 +- site/src/pages/LoginPage/SignInForm.tsx | 204 +- .../pages/LoginPage/TermsOfServiceLink.tsx | 36 +- .../CreateOrganizationPage.tsx | 36 +- .../CreateOrganizationPageView.stories.tsx | 40 +- .../CreateOrganizationPageView.tsx | 222 +- .../CustomRolesPage/CreateEditRolePage.tsx | 132 +- .../CreateEditRolePageView.stories.tsx | 82 +- .../CreateEditRolePageView.tsx | 506 +- .../CustomRolesPage/CustomRolesPage.tsx | 156 +- .../CustomRolesPageView.stories.tsx | 66 +- .../CustomRolesPage/CustomRolesPageView.tsx | 274 +- .../GroupsPage/CreateGroupPage.tsx | 50 +- .../CreateGroupPageView.stories.tsx | 32 +- .../GroupsPage/CreateGroupPageView.tsx | 130 +- .../GroupsPage/GroupPage.tsx | 560 +- .../GroupsPage/GroupSettingsPage.tsx | 106 +- .../GroupSettingsPageView.stories.tsx | 14 +- .../GroupsPage/GroupSettingsPageView.tsx | 248 +- .../GroupsPage/GroupsPage.tsx | 140 +- .../GroupsPage/GroupsPageView.stories.tsx | 54 +- .../GroupsPage/GroupsPageView.tsx | 282 +- .../ManagementSettingsPage/Horizontal.tsx | 128 +- .../ManagementSettingsLayout.tsx | 90 +- .../OrganizationMembersPage.test.tsx | 192 +- .../OrganizationMembersPage.tsx | 122 +- .../OrganizationMembersPageView.stories.tsx | 62 +- .../OrganizationMembersPageView.tsx | 334 +- .../OrganizationSettingsPage.stories.tsx | 82 +- .../OrganizationSettingsPage.test.tsx | 122 +- .../OrganizationSettingsPage.tsx | 152 +- .../OrganizationSettingsPageView.stories.tsx | 20 +- .../OrganizationSettingsPageView.tsx | 298 +- .../OrganizationSummaryPageView.stories.tsx | 20 +- .../OrganizationSummaryPageView.tsx | 70 +- .../pages/ManagementSettingsPage/Sidebar.tsx | 80 +- .../SidebarView.stories.tsx | 344 +- .../ManagementSettingsPage/SidebarView.tsx | 522 +- .../UserTable/EditRolesButton.stories.tsx | 46 +- .../UserTable/EditRolesButton.tsx | 358 +- .../UserTable/TableColumnHelpTooltip.tsx | 84 +- .../UserTable/UserRoleCell.tsx | 346 +- site/src/pages/SetupPage/SetupPage.test.tsx | 236 +- site/src/pages/SetupPage/SetupPage.tsx | 94 +- .../pages/SetupPage/SetupPageView.stories.tsx | 34 +- site/src/pages/SetupPage/SetupPageView.tsx | 632 +- site/src/pages/SetupPage/countries.tsx | 1992 +- .../StarterTemplatePage.tsx | 32 +- .../StarterTemplatePageView.stories.tsx | 26 +- .../StarterTemplatePageView.tsx | 172 +- .../TemplateDocsPage/TemplateDocsPage.tsx | 76 +- .../TemplateEmbedPage.test.tsx | 74 +- .../TemplateEmbedPage/TemplateEmbedPage.tsx | 330 +- .../TemplateEmbedPageView.stories.tsx | 42 +- .../TemplateFilesPage.test.tsx | 74 +- .../TemplateFilesPage/TemplateFilesPage.tsx | 82 +- .../TemplateInsightsPage/DateRange.tsx | 356 +- .../TemplateInsightsPage/IntervalMenu.tsx | 130 +- .../TemplateInsightsPage.stories.tsx | 1712 +- .../TemplateInsightsPage.tsx | 1550 +- .../TemplateInsightsPage/WeekPicker.tsx | 122 +- .../TemplateInsightsPage/utils.ts | 8 +- .../src/pages/TemplatePage/TemplateLayout.tsx | 226 +- .../TemplatePageHeader.stories.tsx | 46 +- .../pages/TemplatePage/TemplatePageHeader.tsx | 376 +- .../TemplateRedirectController.test.tsx | 46 +- .../TemplateRedirectController.tsx | 72 +- .../TemplateStats.stories.tsx | 74 +- .../TemplateSummaryPage/TemplateStats.tsx | 96 +- .../TemplateSummaryPage.tsx | 34 +- .../TemplateSummaryPageView.stories.tsx | 32 +- .../TemplateSummaryPageView.tsx | 66 +- .../TemplateVersionsPage.tsx | 192 +- .../TemplateVersionsPage/VersionRow.tsx | 274 +- .../VersionsTable.stories.tsx | 158 +- .../TemplateVersionsPage/VersionsTable.tsx | 124 +- .../useDeletionDialogState.test.ts | 62 +- .../TemplatePage/useDeletionDialogState.ts | 62 +- site/src/pages/TemplatePage/utils.ts | 10 +- .../pages/TemplateSettingsPage/Sidebar.tsx | 62 +- .../TemplateSettingsForm.tsx | 502 +- .../TemplateSettingsPage.test.tsx | 302 +- .../TemplateSettingsPage.tsx | 130 +- .../TemplateSettingsPageView.stories.tsx | 72 +- .../TemplateSettingsPageView.tsx | 76 +- .../TemplatePermissionsPage.tsx | 180 +- .../TemplatePermissionsPageView.stories.tsx | 28 +- .../TemplatePermissionsPageView.tsx | 694 +- .../UserOrGroupAutocomplete.tsx | 218 +- .../AutostopRequirementHelperText.tsx | 96 +- .../ScheduleDialog.stories.tsx | 36 +- .../TemplateSchedulePage/ScheduleDialog.tsx | 320 +- .../TemplateSchedulePage/TTLHelperText.tsx | 148 +- .../TemplateScheduleAutostart.stories.tsx | 56 +- .../TemplateScheduleAutostart.tsx | 172 +- .../TemplateScheduleForm.tsx | 1144 +- .../TemplateSchedulePage.test.tsx | 574 +- .../TemplateSchedulePage.tsx | 98 +- .../TemplateSchedulePageView.stories.tsx | 46 +- .../TemplateSchedulePageView.tsx | 64 +- .../TemplateSchedulePage/formHelpers.tsx | 160 +- .../useWorkspacesToBeDeleted.ts | 86 +- .../TemplateSettingsLayout.tsx | 112 +- .../TemplateVariableField.tsx | 130 +- .../TemplateVariablesForm.tsx | 308 +- .../TemplateVariablesPage.test.tsx | 164 +- .../TemplateVariablesPage.tsx | 210 +- .../TemplateVariablesPageView.stories.tsx | 110 +- .../TemplateVariablesPageView.tsx | 124 +- .../TemplateVersionEditorPage/FileDialog.tsx | 358 +- .../MissingTemplateVariablesDialog.tsx | 190 +- .../MonacoEditor.tsx | 108 +- .../ProvisionerTagsPopover.stories.tsx | 30 +- .../ProvisionerTagsPopover.test.tsx | 190 +- .../ProvisionerTagsPopover.tsx | 242 +- .../PublishTemplateVersionDialog.tsx | 174 +- .../TemplateVersionEditor.stories.tsx | 140 +- .../TemplateVersionEditor.tsx | 1396 +- .../TemplateVersionEditorPage.test.tsx | 616 +- .../TemplateVersionEditorPage.tsx | 616 +- .../TemplateVersionStatusBadge.tsx | 112 +- .../pages/TemplateVersionEditorPage/types.ts | 6 +- .../TemplateVersionPage.test.tsx | 42 +- .../TemplateVersionPage.tsx | 144 +- .../TemplateVersionPageView.stories.tsx | 66 +- .../TemplateVersionPageView.tsx | 174 +- .../pages/TemplatesPage/EmptyTemplates.tsx | 180 +- .../pages/TemplatesPage/TemplatesFilter.tsx | 126 +- .../TemplatesPage/TemplatesPage.test.tsx | 60 +- .../src/pages/TemplatesPage/TemplatesPage.tsx | 58 +- .../TemplatesPageView.stories.tsx | 172 +- .../pages/TemplatesPage/TemplatesPageView.tsx | 522 +- .../src/pages/TerminalPage/TerminalAlerts.tsx | 314 +- .../TerminalPage/TerminalPage.stories.tsx | 264 +- .../pages/TerminalPage/TerminalPage.test.tsx | 226 +- site/src/pages/TerminalPage/TerminalPage.tsx | 646 +- .../AccountPage/AccountForm.stories.tsx | 62 +- .../AccountPage/AccountForm.test.tsx | 104 +- .../AccountPage/AccountForm.tsx | 140 +- .../AccountPage/AccountPage.test.tsx | 140 +- .../AccountPage/AccountPage.tsx | 62 +- .../AccountPage/AccountUserGroups.stories.tsx | 68 +- .../AccountPage/AccountUserGroups.tsx | 110 +- .../AppearancePage/AppearanceForm.stories.tsx | 18 +- .../AppearancePage/AppearanceForm.tsx | 518 +- .../AppearancePage/AppearancePage.test.tsx | 78 +- .../AppearancePage/AppearancePage.tsx | 54 +- .../ExternalAuthPage/ExternalAuthPage.tsx | 134 +- .../ExternalAuthPageView.stories.tsx | 130 +- .../ExternalAuthPage/ExternalAuthPageView.tsx | 470 +- site/src/pages/UserSettingsPage/Layout.tsx | 36 +- .../NotificationsPage.stories.tsx | 102 +- .../NotificationsPage/NotificationsPage.tsx | 354 +- .../OAuth2ProviderPage/OAuth2ProviderPage.tsx | 92 +- .../OAuth2ProviderPageView.stories.tsx | 36 +- .../OAuth2ProviderPageView.tsx | 128 +- .../SSHKeysPage/SSHKeysPage.test.tsx | 132 +- .../SSHKeysPage/SSHKeysPage.tsx | 94 +- .../SSHKeysPage/SSHKeysPageView.stories.tsx | 42 +- .../SSHKeysPage/SSHKeysPageView.tsx | 110 +- .../SchedulePage/ScheduleForm.stories.tsx | 80 +- .../SchedulePage/ScheduleForm.tsx | 220 +- .../SchedulePage/SchedulePage.test.tsx | 228 +- .../SchedulePage/SchedulePage.tsx | 82 +- site/src/pages/UserSettingsPage/Section.tsx | 126 +- .../SecurityPage/SecurityForm.stories.tsx | 44 +- .../SecurityPage/SecurityForm.tsx | 178 +- .../SecurityPage/SecurityPage.test.tsx | 194 +- .../SecurityPage/SecurityPage.tsx | 114 +- .../SecurityPage/SecurityPageView.stories.tsx | 82 +- .../SecurityPage/SingleSignOnSection.tsx | 492 +- site/src/pages/UserSettingsPage/Sidebar.tsx | 92 +- .../ConfirmDeleteDialog.stories.tsx | 42 +- .../TokensPage/ConfirmDeleteDialog.tsx | 88 +- .../TokensPage/TokensPage.tsx | 104 +- .../TokensPage/TokensPageView.stories.tsx | 58 +- .../TokensPage/TokensPageView.tsx | 192 +- .../UserSettingsPage/TokensPage/hooks.ts | 42 +- .../WorkspaceProxyPage/WorkspaceProxyPage.tsx | 70 +- .../WorkspaceProxyPage/WorkspaceProxyRow.tsx | 308 +- .../WorkspaceProxyPage/WorkspaceProxyView.tsx | 108 +- .../WorspaceProxyView.stories.tsx | 88 +- .../UsersPage/ResetPasswordDialog.stories.tsx | 18 +- .../pages/UsersPage/ResetPasswordDialog.tsx | 94 +- site/src/pages/UsersPage/UsersFilter.tsx | 142 +- site/src/pages/UsersPage/UsersLayout.tsx | 132 +- site/src/pages/UsersPage/UsersPage.test.tsx | 506 +- site/src/pages/UsersPage/UsersPage.tsx | 432 +- .../pages/UsersPage/UsersPageView.stories.tsx | 132 +- site/src/pages/UsersPage/UsersPageView.tsx | 194 +- .../UsersPage/UsersTable/UserGroupsCell.tsx | 210 +- .../UsersTable/UsersTable.stories.tsx | 144 +- .../pages/UsersPage/UsersTable/UsersTable.tsx | 188 +- .../UsersPage/UsersTable/UsersTableBody.tsx | 466 +- site/src/pages/WorkspaceBuildPage/Sidebar.tsx | 126 +- .../WorkspaceBuildPage.test.tsx | 118 +- .../WorkspaceBuildPage/WorkspaceBuildPage.tsx | 84 +- .../WorkspaceBuildPageView.stories.tsx | 50 +- .../WorkspaceBuildPageView.tsx | 448 +- site/src/pages/WorkspacePage/BuildRow.tsx | 180 +- .../ChangeVersionDialog.stories.tsx | 50 +- .../WorkspacePage/ChangeVersionDialog.tsx | 280 +- .../pages/WorkspacePage/HistorySidebar.tsx | 104 +- .../ResourceMetadata.stories.tsx | 96 +- .../pages/WorkspacePage/ResourceMetadata.tsx | 140 +- .../pages/WorkspacePage/ResourcesSidebar.tsx | 186 +- .../WorkspacePage/ResourcesSidebarContent.tsx | 40 +- .../UpdateBuildParametersDialog.tsx | 200 +- .../pages/WorkspacePage/Workspace.stories.tsx | 1224 +- site/src/pages/WorkspacePage/Workspace.tsx | 478 +- .../BuildParametersPopover.tsx | 342 +- .../WorkspaceActions/Buttons.tsx | 300 +- .../WorkspaceActions/DebugButton.stories.tsx | 70 +- .../WorkspaceActions/DebugButton.tsx | 62 +- .../DownloadLogsDialog.stories.tsx | 100 +- .../WorkspaceActions/DownloadLogsDialog.tsx | 482 +- .../WorkspaceActions/RetryButton.stories.tsx | 70 +- .../WorkspaceActions/RetryButton.tsx | 62 +- .../WorkspaceActions.stories.tsx | 286 +- .../WorkspaceActions/WorkspaceActions.tsx | 428 +- .../WorkspaceActions/constants.ts | 274 +- .../WorkspaceBuildLogsSection.tsx | 122 +- .../WorkspaceBuildProgress.stories.tsx | 88 +- .../WorkspacePage/WorkspaceBuildProgress.tsx | 244 +- .../WorkspaceDeleteDialog.stories.tsx | 40 +- .../WorkspaceDeleteDialog.tsx | 342 +- .../WorkspaceDeletedBanner.stories.tsx | 4 +- .../WorkspacePage/WorkspaceDeletedBanner.tsx | 24 +- .../WorkspaceNotifications/Notifications.tsx | 194 +- .../WorkspaceNotifications.stories.tsx | 352 +- .../WorkspaceNotifications.tsx | 422 +- .../WorkspacePage/WorkspacePage.test.tsx | 856 +- .../src/pages/WorkspacePage/WorkspacePage.tsx | 194 +- .../WorkspacePage/WorkspaceReadyPage.tsx | 694 +- .../WorkspaceScheduleControls.test.tsx | 222 +- .../WorkspaceScheduleControls.tsx | 484 +- .../WorkspacePage/WorkspaceTopbar.stories.tsx | 468 +- .../pages/WorkspacePage/WorkspaceTopbar.tsx | 488 +- site/src/pages/WorkspacePage/permissions.ts | 66 +- .../WorkspacePage/useResourcesNav.test.tsx | 274 +- .../pages/WorkspacePage/useResourcesNav.ts | 66 +- .../pages/WorkspaceSettingsPage/Sidebar.tsx | 52 +- .../WorkspaceParametersForm.tsx | 272 +- .../WorkspaceParametersPage.stories.tsx | 152 +- .../WorkspaceParametersPage.test.tsx | 128 +- .../WorkspaceParametersPage.tsx | 252 +- .../WorkspaceScheduleForm.stories.tsx | 162 +- .../WorkspaceScheduleForm.test.tsx | 744 +- .../WorkspaceScheduleForm.tsx | 802 +- .../WorkspaceSchedulePage.test.tsx | 584 +- .../WorkspaceSchedulePage.tsx | 248 +- .../WorkspaceSchedulePage/formToRequest.ts | 116 +- .../WorkspaceSchedulePage/schedule.test.ts | 128 +- .../WorkspaceSchedulePage/schedule.ts | 126 +- .../WorkspaceSchedulePage/ttl.ts | 10 +- .../WorkspaceSettingsForm.tsx | 204 +- .../WorkspaceSettingsLayout.tsx | 90 +- .../WorkspaceSettingsPage.test.tsx | 92 +- .../WorkspaceSettingsPage.tsx | 72 +- .../WorkspaceSettingsPageView.stories.tsx | 20 +- .../WorkspaceSettingsPageView.tsx | 50 +- .../BatchDeleteConfirmation.stories.tsx | 50 +- .../BatchDeleteConfirmation.tsx | 486 +- .../BatchUpdateConfirmation.stories.tsx | 110 +- .../BatchUpdateConfirmation.tsx | 790 +- site/src/pages/WorkspacesPage/LastUsed.tsx | 100 +- .../WorkspacesPage/WorkspaceHelpTooltip.tsx | 60 +- .../pages/WorkspacesPage/WorkspacesButton.tsx | 366 +- .../pages/WorkspacesPage/WorkspacesEmpty.tsx | 318 +- .../WorkspacesPage/WorkspacesPage.test.tsx | 524 +- .../pages/WorkspacesPage/WorkspacesPage.tsx | 276 +- .../WorkspacesPageView.stories.tsx | 366 +- .../WorkspacesPage/WorkspacesPageView.tsx | 382 +- .../pages/WorkspacesPage/WorkspacesTable.tsx | 524 +- .../src/pages/WorkspacesPage/batchActions.tsx | 172 +- site/src/pages/WorkspacesPage/data.ts | 192 +- .../pages/WorkspacesPage/filter/filter.tsx | 158 +- .../src/pages/WorkspacesPage/filter/menus.tsx | 180 +- site/src/router.tsx | 646 +- site/src/testHelpers/chromatic.ts | 16 +- site/src/testHelpers/entities.ts | 6492 ++-- site/src/testHelpers/handlers.ts | 672 +- site/src/testHelpers/hooks.tsx | 286 +- site/src/testHelpers/localStorage.ts | 56 +- site/src/testHelpers/renderHelpers.tsx | 368 +- site/src/testHelpers/storybook.tsx | 182 +- site/src/theme/constants.ts | 2 +- site/src/theme/dark/experimental.ts | 80 +- site/src/theme/dark/index.ts | 10 +- site/src/theme/dark/monaco.ts | 64 +- site/src/theme/dark/mui.ts | 134 +- site/src/theme/dark/roles.ts | 300 +- site/src/theme/darkBlue/experimental.ts | 80 +- site/src/theme/darkBlue/index.ts | 10 +- site/src/theme/darkBlue/monaco.ts | 64 +- site/src/theme/darkBlue/mui.ts | 134 +- site/src/theme/darkBlue/roles.ts | 300 +- site/src/theme/experimental.ts | 4 +- site/src/theme/externalImages.test.ts | 136 +- site/src/theme/externalImages.ts | 226 +- site/src/theme/icons.json | 182 +- site/src/theme/index.ts | 14 +- site/src/theme/light/experimental.ts | 80 +- site/src/theme/light/index.ts | 10 +- site/src/theme/light/monaco.ts | 64 +- site/src/theme/light/mui.ts | 446 +- site/src/theme/light/roles.ts | 300 +- site/src/theme/mui.ts | 924 +- site/src/theme/roles.ts | 88 +- site/src/theme/tailwindColors.ts | 578 +- site/src/utils/appearance.ts | 22 +- site/src/utils/apps.test.ts | 186 +- site/src/utils/apps.ts | 56 +- site/src/utils/buildInfo.ts | 28 +- site/src/utils/colors.test.ts | 118 +- site/src/utils/colors.ts | 88 +- site/src/utils/createDayString.ts | 2 +- site/src/utils/delay.ts | 6 +- site/src/utils/deployOptions.ts | 54 +- site/src/utils/docs.ts | 54 +- site/src/utils/dormant.test.ts | 72 +- site/src/utils/dormant.ts | 24 +- site/src/utils/ellipsizeText.test.ts | 32 +- site/src/utils/ellipsizeText.ts | 16 +- site/src/utils/events.test.ts | 24 +- site/src/utils/events.ts | 16 +- site/src/utils/filetree.test.ts | 202 +- site/src/utils/filetree.ts | 128 +- site/src/utils/filters.ts | 2 +- site/src/utils/formUtils.stories.tsx | 72 +- site/src/utils/formUtils.test.ts | 348 +- site/src/utils/formUtils.ts | 198 +- site/src/utils/groups.ts | 24 +- site/src/utils/latency.ts | 20 +- site/src/utils/page.ts | 2 +- site/src/utils/portForward.ts | 126 +- site/src/utils/provisionerJob.ts | 10 +- site/src/utils/random.ts | 18 +- site/src/utils/redirect.test.ts | 32 +- site/src/utils/redirect.ts | 12 +- site/src/utils/richParameters.test.ts | 92 +- site/src/utils/richParameters.ts | 342 +- site/src/utils/schedule.test.ts | 142 +- site/src/utils/schedule.tsx | 434 +- site/src/utils/starterTemplates.ts | 26 +- site/src/utils/tar.test.ts | 100 +- site/src/utils/tar.ts | 564 +- site/src/utils/telemetry.ts | 52 +- site/src/utils/templateVersion.ts | 50 +- site/src/utils/templates.ts | 16 +- site/src/utils/terminal.ts | 64 +- site/src/utils/time.ts | 30 +- site/src/utils/timeZones.ts | 2 +- site/src/utils/workspace.test.ts | 290 +- site/src/utils/workspace.tsx | 434 +- 961 files changed, 112866 insertions(+), 112874 deletions(-) rename site/src/api/{rbacresources_gen.ts => rbacresourcesGenerated.ts} (100%) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 1464c029a3..de550f174b 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,13 +1,13 @@ { - "name": "Development environments on your infrastructure", - "image": "codercom/oss-dogfood:latest", + "name": "Development environments on your infrastructure", + "image": "codercom/oss-dogfood:latest", - "features": { - // See all possible options here https://github.com/devcontainers/features/tree/main/src/docker-in-docker - "ghcr.io/devcontainers/features/docker-in-docker:2": { - "moby": "false" - } - }, - // SYS_PTRACE to enable go debugging - "runArgs": ["--cap-add=SYS_PTRACE"] + "features": { + // See all possible options here https://github.com/devcontainers/features/tree/main/src/docker-in-docker + "ghcr.io/devcontainers/features/docker-in-docker:2": { + "moby": "false" + } + }, + // SYS_PTRACE to enable go debugging + "runArgs": ["--cap-add=SYS_PTRACE"] } diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml index d429552b5b..3bdc208efd 100644 --- a/.github/dependabot.yaml +++ b/.github/dependabot.yaml @@ -95,10 +95,6 @@ updates: - "@emotion*" exclude-patterns: - "jest-runner-eslint" - eslint: - patterns: - - "eslint*" - - "@typescript-eslint*" jest: patterns: - "jest" diff --git a/.github/workflows/mlc_config.json b/.github/workflows/mlc_config.json index f26a02a72e..4905e50e21 100644 --- a/.github/workflows/mlc_config.json +++ b/.github/workflows/mlc_config.json @@ -1,26 +1,26 @@ { - "ignorePatterns": [ - { - "pattern": "://localhost" - }, - { - "pattern": "://.*.?example\\.com" - }, - { - "pattern": "developer.github.com" - }, - { - "pattern": "docs.github.com" - }, - { - "pattern": "support.google.com" - }, - { - "pattern": "tailscale.com" - }, - { - "pattern": "wireguard.com" - } - ], - "aliveStatusCodes": [200, 0] + "ignorePatterns": [ + { + "pattern": "://localhost" + }, + { + "pattern": "://.*.?example\\.com" + }, + { + "pattern": "developer.github.com" + }, + { + "pattern": "docs.github.com" + }, + { + "pattern": "support.google.com" + }, + { + "pattern": "tailscale.com" + }, + { + "pattern": "wireguard.com" + } + ], + "aliveStatusCodes": [200, 0] } diff --git a/.prettierrc.yaml b/.prettierrc.yaml index f42aeede2f..c410527e0a 100644 --- a/.prettierrc.yaml +++ b/.prettierrc.yaml @@ -4,7 +4,7 @@ printWidth: 80 proseWrap: always trailingComma: all -useTabs: false +useTabs: true tabWidth: 2 overrides: - files: diff --git a/.vscode/extensions.json b/.vscode/extensions.json index a92dd32cce..c885d6edf3 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,15 +1,15 @@ { - "recommendations": [ - "github.vscode-codeql", - "golang.go", - "hashicorp.terraform", - "esbenp.prettier-vscode", - "foxundermoon.shell-format", - "emeraldwalk.runonsave", - "zxh404.vscode-proto3", - "redhat.vscode-yaml", - "streetsidesoftware.code-spell-checker", - "EditorConfig.EditorConfig", - "biomejs.biome" - ] + "recommendations": [ + "github.vscode-codeql", + "golang.go", + "hashicorp.terraform", + "esbenp.prettier-vscode", + "foxundermoon.shell-format", + "emeraldwalk.runonsave", + "zxh404.vscode-proto3", + "redhat.vscode-yaml", + "streetsidesoftware.code-spell-checker", + "EditorConfig.EditorConfig", + "biomejs.biome" + ] } diff --git a/.vscode/settings.json b/.vscode/settings.json index 0d01151dce..82ce10e888 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,238 +1,238 @@ { - "cSpell.words": [ - "afero", - "agentsdk", - "apps", - "ASKPASS", - "authcheck", - "autostop", - "awsidentity", - "bodyclose", - "buildinfo", - "buildname", - "circbuf", - "cliflag", - "cliui", - "codecov", - "coderd", - "coderdenttest", - "coderdtest", - "codersdk", - "contravariance", - "cronstrue", - "databasefake", - "dbgen", - "dbmem", - "dbtype", - "DERP", - "derphttp", - "derpmap", - "devel", - "devtunnel", - "dflags", - "drpc", - "drpcconn", - "drpcmux", - "drpcserver", - "Dsts", - "embeddedpostgres", - "enablements", - "enterprisemeta", - "errgroup", - "eventsourcemock", - "externalauth", - "Failf", - "fatih", - "Formik", - "gitauth", - "gitsshkey", - "goarch", - "gographviz", - "goleak", - "gonet", - "gossh", - "gsyslog", - "GTTY", - "hashicorp", - "hclsyntax", - "httpapi", - "httpmw", - "idtoken", - "Iflag", - "incpatch", - "initialisms", - "ipnstate", - "isatty", - "Jobf", - "Keygen", - "kirsle", - "Kubernetes", - "ldflags", - "magicsock", - "manifoldco", - "mapstructure", - "mattn", - "mitchellh", - "moby", - "namesgenerator", - "namespacing", - "netaddr", - "netip", - "netmap", - "netns", - "netstack", - "nettype", - "nfpms", - "nhooyr", - "nmcfg", - "nolint", - "nosec", - "ntqry", - "OIDC", - "oneof", - "opty", - "paralleltest", - "parameterscopeid", - "pqtype", - "prometheusmetrics", - "promhttp", - "protobuf", - "provisionerd", - "provisionerdserver", - "provisionersdk", - "ptty", - "ptys", - "ptytest", - "quickstart", - "reconfig", - "replicasync", - "retrier", - "rpty", - "SCIM", - "sdkproto", - "sdktrace", - "Signup", - "slogtest", - "sourcemapped", - "spinbutton", - "Srcs", - "stdbuf", - "stretchr", - "STTY", - "stuntest", - "tailbroker", - "tailcfg", - "tailexchange", - "tailnet", - "tailnettest", - "Tailscale", - "tanstack", - "tbody", - "TCGETS", - "tcpip", - "TCSETS", - "templateversions", - "testdata", - "testid", - "testutil", - "tfexec", - "tfjson", - "tfplan", - "tfstate", - "thead", - "tios", - "tmpdir", - "tokenconfig", - "Topbar", - "tparallel", - "trialer", - "trimprefix", - "tsdial", - "tslogger", - "tstun", - "turnconn", - "typegen", - "typesafe", - "unconvert", - "Untar", - "Userspace", - "VMID", - "walkthrough", - "weblinks", - "webrtc", - "wgcfg", - "wgconfig", - "wgengine", - "wgmonitor", - "wgnet", - "workspaceagent", - "workspaceagents", - "workspaceapp", - "workspaceapps", - "workspacebuilds", - "workspacename", - "wsjson", - "xerrors", - "xlarge", - "xsmall", - "yamux" - ], - "cSpell.ignorePaths": ["site/package.json", ".vscode/settings.json"], - "emeraldwalk.runonsave": { - "commands": [ - { - "match": "database/queries/*.sql", - "cmd": "make gen" - }, - { - "match": "provisionerd/proto/provisionerd.proto", - "cmd": "make provisionerd/proto/provisionerd.pb.go" - } - ] - }, - "search.exclude": { - "**.pb.go": true, - "**/*.gen.json": true, - "**/testdata/*": true, - "coderd/apidoc/**": true, - "docs/reference/api/*.md": true, - "docs/reference/cli/*.md": true, - "docs/templates/*.md": true, - "LICENSE": true, - "scripts/metricsdocgen/metrics": true, - "site/out/**": true, - "site/storybook-static/**": true, - "**.map": true, - "pnpm-lock.yaml": true - }, - // Ensure files always have a newline. - "files.insertFinalNewline": true, - "go.lintTool": "golangci-lint", - "go.lintFlags": ["--fast"], - "go.coverageDecorator": { - "type": "gutter", - "coveredGutterStyle": "blockgreen", - "uncoveredGutterStyle": "blockred" - }, - // The codersdk is used by coderd another other packages extensively. - // To reduce redundancy in tests, it's covered by other packages. - // Since package coverage pairing can't be defined, all packages cover - // all other packages. - "go.testFlags": ["-short", "-coverpkg=./..."], - // We often use a version of TypeScript that's ahead of the version shipped - // with VS Code. - "typescript.tsdk": "./site/node_modules/typescript/lib", - // Playwright tests in VSCode will open a browser to live "view" the test. - "playwright.reuseBrowser": true, + "cSpell.words": [ + "afero", + "agentsdk", + "apps", + "ASKPASS", + "authcheck", + "autostop", + "awsidentity", + "bodyclose", + "buildinfo", + "buildname", + "circbuf", + "cliflag", + "cliui", + "codecov", + "coderd", + "coderdenttest", + "coderdtest", + "codersdk", + "contravariance", + "cronstrue", + "databasefake", + "dbgen", + "dbmem", + "dbtype", + "DERP", + "derphttp", + "derpmap", + "devel", + "devtunnel", + "dflags", + "drpc", + "drpcconn", + "drpcmux", + "drpcserver", + "Dsts", + "embeddedpostgres", + "enablements", + "enterprisemeta", + "errgroup", + "eventsourcemock", + "externalauth", + "Failf", + "fatih", + "Formik", + "gitauth", + "gitsshkey", + "goarch", + "gographviz", + "goleak", + "gonet", + "gossh", + "gsyslog", + "GTTY", + "hashicorp", + "hclsyntax", + "httpapi", + "httpmw", + "idtoken", + "Iflag", + "incpatch", + "initialisms", + "ipnstate", + "isatty", + "Jobf", + "Keygen", + "kirsle", + "Kubernetes", + "ldflags", + "magicsock", + "manifoldco", + "mapstructure", + "mattn", + "mitchellh", + "moby", + "namesgenerator", + "namespacing", + "netaddr", + "netip", + "netmap", + "netns", + "netstack", + "nettype", + "nfpms", + "nhooyr", + "nmcfg", + "nolint", + "nosec", + "ntqry", + "OIDC", + "oneof", + "opty", + "paralleltest", + "parameterscopeid", + "pqtype", + "prometheusmetrics", + "promhttp", + "protobuf", + "provisionerd", + "provisionerdserver", + "provisionersdk", + "ptty", + "ptys", + "ptytest", + "quickstart", + "reconfig", + "replicasync", + "retrier", + "rpty", + "SCIM", + "sdkproto", + "sdktrace", + "Signup", + "slogtest", + "sourcemapped", + "spinbutton", + "Srcs", + "stdbuf", + "stretchr", + "STTY", + "stuntest", + "tailbroker", + "tailcfg", + "tailexchange", + "tailnet", + "tailnettest", + "Tailscale", + "tanstack", + "tbody", + "TCGETS", + "tcpip", + "TCSETS", + "templateversions", + "testdata", + "testid", + "testutil", + "tfexec", + "tfjson", + "tfplan", + "tfstate", + "thead", + "tios", + "tmpdir", + "tokenconfig", + "Topbar", + "tparallel", + "trialer", + "trimprefix", + "tsdial", + "tslogger", + "tstun", + "turnconn", + "typegen", + "typesafe", + "unconvert", + "Untar", + "Userspace", + "VMID", + "walkthrough", + "weblinks", + "webrtc", + "wgcfg", + "wgconfig", + "wgengine", + "wgmonitor", + "wgnet", + "workspaceagent", + "workspaceagents", + "workspaceapp", + "workspaceapps", + "workspacebuilds", + "workspacename", + "wsjson", + "xerrors", + "xlarge", + "xsmall", + "yamux" + ], + "cSpell.ignorePaths": ["site/package.json", ".vscode/settings.json"], + "emeraldwalk.runonsave": { + "commands": [ + { + "match": "database/queries/*.sql", + "cmd": "make gen" + }, + { + "match": "provisionerd/proto/provisionerd.proto", + "cmd": "make provisionerd/proto/provisionerd.pb.go" + } + ] + }, + "search.exclude": { + "**.pb.go": true, + "**/*.gen.json": true, + "**/testdata/*": true, + "coderd/apidoc/**": true, + "docs/reference/api/*.md": true, + "docs/reference/cli/*.md": true, + "docs/templates/*.md": true, + "LICENSE": true, + "scripts/metricsdocgen/metrics": true, + "site/out/**": true, + "site/storybook-static/**": true, + "**.map": true, + "pnpm-lock.yaml": true + }, + // Ensure files always have a newline. + "files.insertFinalNewline": true, + "go.lintTool": "golangci-lint", + "go.lintFlags": ["--fast"], + "go.coverageDecorator": { + "type": "gutter", + "coveredGutterStyle": "blockgreen", + "uncoveredGutterStyle": "blockred" + }, + // The codersdk is used by coderd another other packages extensively. + // To reduce redundancy in tests, it's covered by other packages. + // Since package coverage pairing can't be defined, all packages cover + // all other packages. + "go.testFlags": ["-short", "-coverpkg=./..."], + // We often use a version of TypeScript that's ahead of the version shipped + // with VS Code. + "typescript.tsdk": "./site/node_modules/typescript/lib", + // Playwright tests in VSCode will open a browser to live "view" the test. + "playwright.reuseBrowser": true, - "[javascript][javascriptreact][json][jsonc][typescript][typescriptreact]": { - "editor.defaultFormatter": "biomejs.biome" - // "editor.codeActionsOnSave": { - // "source.organizeImports.biome": "explicit" - // } - }, + "[javascript][javascriptreact][json][jsonc][typescript][typescriptreact]": { + "editor.defaultFormatter": "biomejs.biome" + // "editor.codeActionsOnSave": { + // "source.organizeImports.biome": "explicit" + // } + }, - "[css][html][markdown][yaml]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" - } + "[css][html][markdown][yaml]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + } } diff --git a/Makefile b/Makefile index d5654e6279..f608c4965d 100644 --- a/Makefile +++ b/Makefile @@ -491,7 +491,7 @@ gen: \ site/src/api/typesGenerated.ts \ coderd/rbac/object_gen.go \ codersdk/rbacresources_gen.go \ - site/src/api/rbacresources_gen.ts \ + site/src/api/rbacresourcesGenerated.ts \ docs/admin/prometheus.md \ docs/reference/cli/README.md \ docs/admin/audit-logs.md \ @@ -520,7 +520,7 @@ gen/mark-fresh: site/src/api/typesGenerated.ts \ coderd/rbac/object_gen.go \ codersdk/rbacresources_gen.go \ - site/src/api/rbacresources_gen.ts \ + site/src/api/rbacresourcesGenerated.ts \ docs/admin/prometheus.md \ docs/reference/cli/README.md \ docs/admin/audit-logs.md \ @@ -621,8 +621,8 @@ coderd/rbac/object_gen.go: scripts/rbacgen/rbacobject.gotmpl scripts/rbacgen/mai codersdk/rbacresources_gen.go: scripts/rbacgen/codersdk.gotmpl scripts/rbacgen/main.go coderd/rbac/object.go coderd/rbac/policy/policy.go go run scripts/rbacgen/main.go codersdk > codersdk/rbacresources_gen.go -site/src/api/rbacresources_gen.ts: scripts/rbacgen/codersdk.gotmpl scripts/rbacgen/main.go coderd/rbac/object.go coderd/rbac/policy/policy.go - go run scripts/rbacgen/main.go typescript > site/src/api/rbacresources_gen.ts +site/src/api/rbacresourcesGenerated.ts: scripts/rbacgen/codersdk.gotmpl scripts/rbacgen/main.go coderd/rbac/object.go coderd/rbac/policy/policy.go + go run scripts/rbacgen/main.go typescript > "$@" docs/admin/prometheus.md: scripts/metricsdocgen/main.go scripts/metricsdocgen/metrics diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 94a8939ed7..5f2ed6e5aa 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -1,14299 +1,14299 @@ { - "swagger": "2.0", - "info": { - "description": "Coderd is the service created by running coder server. It is a thin API that connects workspaces, provisioners and users. coderd stores its state in Postgres and is the only service that communicates with Postgres.", - "title": "Coder API", - "termsOfService": "https://coder.com/legal/terms-of-service", - "contact": { - "name": "API Support", - "url": "https://coder.com", - "email": "support@coder.com" - }, - "license": { - "name": "AGPL-3.0", - "url": "https://github.com/coder/coder/blob/main/LICENSE" - }, - "version": "2.0" - }, - "basePath": "/api/v2", - "paths": { - "/": { - "get": { - "produces": ["application/json"], - "tags": ["General"], - "summary": "API root handler", - "operationId": "api-root-handler", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - } - }, - "/appearance": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Get appearance", - "operationId": "get-appearance", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.AppearanceConfig" - } - } - } - }, - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Update appearance", - "operationId": "update-appearance", - "parameters": [ - { - "description": "Update appearance request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateAppearanceConfig" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.UpdateAppearanceConfig" - } - } - } - } - }, - "/applications/auth-redirect": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "tags": ["Applications"], - "summary": "Redirect to URI with encrypted API key", - "operationId": "redirect-to-uri-with-encrypted-api-key", - "parameters": [ - { - "type": "string", - "description": "Redirect destination", - "name": "redirect_uri", - "in": "query" - } - ], - "responses": { - "307": { - "description": "Temporary Redirect" - } - } - } - }, - "/applications/host": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Applications"], - "summary": "Get applications host", - "operationId": "get-applications-host", - "deprecated": true, - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.AppHostResponse" - } - } - } - } - }, - "/applications/reconnecting-pty-signed-token": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Issue signed app token for reconnecting PTY", - "operationId": "issue-signed-app-token-for-reconnecting-pty", - "parameters": [ - { - "description": "Issue reconnecting PTY signed token request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.IssueReconnectingPTYSignedTokenRequest" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.IssueReconnectingPTYSignedTokenResponse" - } - } - }, - "x-apidocgen": { - "skip": true - } - } - }, - "/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" - }, - { - "type": "integer", - "description": "Page limit", - "name": "limit", - "in": "query", - "required": true - }, - { - "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-log", - "parameters": [ - { - "description": "Audit log request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.CreateTestAuditLogRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - } - }, - "x-apidocgen": { - "skip": true - } - } - }, - "/authcheck": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Authorization"], - "summary": "Check authorization", - "operationId": "check-authorization", - "parameters": [ - { - "description": "Authorization request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.AuthorizationRequest" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.AuthorizationResponse" - } - } - } - } - }, - "/buildinfo": { - "get": { - "produces": ["application/json"], - "tags": ["General"], - "summary": "Build info", - "operationId": "build-info", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.BuildInfoResponse" - } - } - } - } - }, - "/csp/reports": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "tags": ["General"], - "summary": "Report CSP violations", - "operationId": "report-csp-violations", - "parameters": [ - { - "description": "Violation report", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/coderd.cspViolation" - } - } - ], - "responses": { - "200": { - "description": "OK" - } - } - } - }, - "/debug/coordinator": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["text/html"], - "tags": ["Debug"], - "summary": "Debug Info Wireguard Coordinator", - "operationId": "debug-info-wireguard-coordinator", - "responses": { - "200": { - "description": "OK" - } - } - } - }, - "/debug/derp/traffic": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Debug"], - "summary": "Debug DERP traffic", - "operationId": "debug-derp-traffic", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/derp.BytesSentRecv" - } - } - } - }, - "x-apidocgen": { - "skip": true - } - } - }, - "/debug/expvar": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Debug"], - "summary": "Debug expvar", - "operationId": "debug-expvar", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "object", - "additionalProperties": true - } - } - }, - "x-apidocgen": { - "skip": true - } - } - }, - "/debug/health": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Debug"], - "summary": "Debug Info Deployment Health", - "operationId": "debug-info-deployment-health", - "parameters": [ - { - "type": "boolean", - "description": "Force a healthcheck to run", - "name": "force", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/healthsdk.HealthcheckReport" - } - } - } - } - }, - "/debug/health/settings": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Debug"], - "summary": "Get health settings", - "operationId": "get-health-settings", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/healthsdk.HealthSettings" - } - } - } - }, - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Debug"], - "summary": "Update health settings", - "operationId": "update-health-settings", - "parameters": [ - { - "description": "Update health settings", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/healthsdk.UpdateHealthSettings" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/healthsdk.UpdateHealthSettings" - } - } - } - } - }, - "/debug/tailnet": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["text/html"], - "tags": ["Debug"], - "summary": "Debug Info Tailnet", - "operationId": "debug-info-tailnet", - "responses": { - "200": { - "description": "OK" - } - } - } - }, - "/debug/ws": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Debug"], - "summary": "Debug Info Websocket Test", - "operationId": "debug-info-websocket-test", - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - }, - "x-apidocgen": { - "skip": true - } - } - }, - "/debug/{user}/debug-link": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "tags": ["Agents"], - "summary": "Debug OIDC context for a user", - "operationId": "debug-oidc-context-for-a-user", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "Success" - } - }, - "x-apidocgen": { - "skip": true - } - } - }, - "/deployment/config": { - "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" - } - } - } - } - }, - "/deployment/ssh": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["General"], - "summary": "SSH Config", - "operationId": "ssh-config", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.SSHConfigResponse" - } - } - } - } - }, - "/deployment/stats": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["General"], - "summary": "Get deployment stats", - "operationId": "get-deployment-stats", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.DeploymentStats" - } - } - } - } - }, - "/derp-map": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "tags": ["Agents"], - "summary": "Get DERP map updates", - "operationId": "get-derp-map-updates", - "responses": { - "101": { - "description": "Switching Protocols" - } - } - } - }, - "/entitlements": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Get entitlements", - "operationId": "get-entitlements", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Entitlements" - } - } - } - } - }, - "/experiments": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["General"], - "summary": "Get enabled experiments", - "operationId": "get-enabled-experiments", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Experiment" - } - } - } - } - } - }, - "/experiments/available": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["General"], - "summary": "Get safe experiments", - "operationId": "get-safe-experiments", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Experiment" - } - } - } - } - } - }, - "/external-auth": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Git"], - "summary": "Get user external auths", - "operationId": "get-user-external-auths", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.ExternalAuthLink" - } - } - } - } - }, - "/external-auth/{externalauth}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Git"], - "summary": "Get external auth by ID", - "operationId": "get-external-auth-by-id", - "parameters": [ - { - "type": "string", - "format": "string", - "description": "Git Provider ID", - "name": "externalauth", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.ExternalAuth" - } - } - } - }, - "delete": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "tags": ["Git"], - "summary": "Delete external auth user link by ID", - "operationId": "delete-external-auth-user-link-by-id", - "parameters": [ - { - "type": "string", - "format": "string", - "description": "Git Provider ID", - "name": "externalauth", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK" - } - } - } - }, - "/external-auth/{externalauth}/device": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Git"], - "summary": "Get external auth device by ID.", - "operationId": "get-external-auth-device-by-id", - "parameters": [ - { - "type": "string", - "format": "string", - "description": "Git Provider ID", - "name": "externalauth", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.ExternalAuthDevice" - } - } - } - }, - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "tags": ["Git"], - "summary": "Post external auth device by ID", - "operationId": "post-external-auth-device-by-id", - "parameters": [ - { - "type": "string", - "format": "string", - "description": "External Provider ID", - "name": "externalauth", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content" - } - } - } - }, - "/files": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "description": "Swagger 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": "upload-file", - "parameters": [ - { - "type": "string", - "default": "application/x-tar", - "description": "Content-Type must be `application/x-tar` or `application/zip`", - "name": "Content-Type", - "in": "header", - "required": true - }, - { - "type": "file", - "description": "File to be uploaded. If using tar format, file must conform to ustar (pax may cause problems).", - "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" - } - } - } - }, - "/groups": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Get groups", - "operationId": "get-groups", - "parameters": [ - { - "type": "string", - "description": "Organization ID or name", - "name": "organization", - "in": "query", - "required": true - }, - { - "type": "string", - "description": "User ID or name", - "name": "has_member", - "in": "query", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Group" - } - } - } - } - } - }, - "/groups/{group}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Get group by ID", - "operationId": "get-group-by-id", - "parameters": [ - { - "type": "string", - "description": "Group id", - "name": "group", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Group" - } - } - } - }, - "delete": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Delete group by name", - "operationId": "delete-group-by-name", - "parameters": [ - { - "type": "string", - "description": "Group name", - "name": "group", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Group" - } - } - } - }, - "patch": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Update group by name", - "operationId": "update-group-by-name", - "parameters": [ - { - "type": "string", - "description": "Group name", - "name": "group", - "in": "path", - "required": true - }, - { - "description": "Patch group request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.PatchGroupRequest" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Group" - } - } - } - } - }, - "/insights/daus": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Insights"], - "summary": "Get deployment DAUs", - "operationId": "get-deployment-daus", - "parameters": [ - { - "type": "integer", - "description": "Time-zone offset (e.g. -2)", - "name": "tz_offset", - "in": "query", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.DAUsResponse" - } - } - } - } - }, - "/insights/templates": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Insights"], - "summary": "Get insights about templates", - "operationId": "get-insights-about-templates", - "parameters": [ - { - "type": "string", - "format": "date-time", - "description": "Start time", - "name": "start_time", - "in": "query", - "required": true - }, - { - "type": "string", - "format": "date-time", - "description": "End time", - "name": "end_time", - "in": "query", - "required": true - }, - { - "enum": ["week", "day"], - "type": "string", - "description": "Interval", - "name": "interval", - "in": "query", - "required": true - }, - { - "type": "array", - "items": { - "type": "string" - }, - "collectionFormat": "csv", - "description": "Template IDs", - "name": "template_ids", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.TemplateInsightsResponse" - } - } - } - } - }, - "/insights/user-activity": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Insights"], - "summary": "Get insights about user activity", - "operationId": "get-insights-about-user-activity", - "parameters": [ - { - "type": "string", - "format": "date-time", - "description": "Start time", - "name": "start_time", - "in": "query", - "required": true - }, - { - "type": "string", - "format": "date-time", - "description": "End time", - "name": "end_time", - "in": "query", - "required": true - }, - { - "type": "array", - "items": { - "type": "string" - }, - "collectionFormat": "csv", - "description": "Template IDs", - "name": "template_ids", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.UserActivityInsightsResponse" - } - } - } - } - }, - "/insights/user-latency": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Insights"], - "summary": "Get insights about user latency", - "operationId": "get-insights-about-user-latency", - "parameters": [ - { - "type": "string", - "format": "date-time", - "description": "Start time", - "name": "start_time", - "in": "query", - "required": true - }, - { - "type": "string", - "format": "date-time", - "description": "End time", - "name": "end_time", - "in": "query", - "required": true - }, - { - "type": "array", - "items": { - "type": "string" - }, - "collectionFormat": "csv", - "description": "Template IDs", - "name": "template_ids", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.UserLatencyInsightsResponse" - } - } - } - } - }, - "/integrations/jfrog/xray-scan": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Get JFrog XRay scan by workspace agent ID.", - "operationId": "get-jfrog-xray-scan-by-workspace-agent-id", - "parameters": [ - { - "type": "string", - "description": "Workspace ID", - "name": "workspace_id", - "in": "query", - "required": true - }, - { - "type": "string", - "description": "Agent ID", - "name": "agent_id", - "in": "query", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.JFrogXrayScan" - } - } - } - }, - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Post JFrog XRay scan by workspace agent ID.", - "operationId": "post-jfrog-xray-scan-by-workspace-agent-id", - "parameters": [ - { - "description": "Post JFrog XRay scan request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.JFrogXrayScan" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - } - }, - "/licenses": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Get licenses", - "operationId": "get-licenses", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.License" - } - } - } - } - }, - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Organizations"], - "summary": "Add new license", - "operationId": "add-new-license", - "parameters": [ - { - "description": "Add license request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.AddLicenseRequest" - } - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/codersdk.License" - } - } - } - } - }, - "/licenses/refresh-entitlements": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Organizations"], - "summary": "Update license entitlements", - "operationId": "update-license-entitlements", - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - } - }, - "/licenses/{id}": { - "delete": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Delete license", - "operationId": "delete-license", - "parameters": [ - { - "type": "string", - "format": "number", - "description": "License ID", - "name": "id", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK" - } - } - } - }, - "/notifications/dispatch-methods": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Notifications"], - "summary": "Get notification dispatch methods", - "operationId": "get-notification-dispatch-methods", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.NotificationMethodsResponse" - } - } - } - } - } - }, - "/notifications/settings": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Notifications"], - "summary": "Get notifications settings", - "operationId": "get-notifications-settings", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.NotificationsSettings" - } - } - } - }, - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Notifications"], - "summary": "Update notifications settings", - "operationId": "update-notifications-settings", - "parameters": [ - { - "description": "Notifications settings request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.NotificationsSettings" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.NotificationsSettings" - } - }, - "304": { - "description": "Not Modified" - } - } - } - }, - "/notifications/templates/system": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Notifications"], - "summary": "Get system notification templates", - "operationId": "get-system-notification-templates", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.NotificationTemplate" - } - } - } - } - } - }, - "/notifications/templates/{notification_template}/method": { - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Update notification template dispatch method", - "operationId": "update-notification-template-dispatch-method", - "parameters": [ - { - "type": "string", - "description": "Notification template UUID", - "name": "notification_template", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "Success" - }, - "304": { - "description": "Not modified" - } - } - } - }, - "/oauth2-provider/apps": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Get OAuth2 applications.", - "operationId": "get-oauth2-applications", - "parameters": [ - { - "type": "string", - "description": "Filter by applications authorized for a user", - "name": "user_id", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.OAuth2ProviderApp" - } - } - } - } - }, - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Create OAuth2 application.", - "operationId": "create-oauth2-application", - "parameters": [ - { - "description": "The OAuth2 application to create.", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.PostOAuth2ProviderAppRequest" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.OAuth2ProviderApp" - } - } - } - } - }, - "/oauth2-provider/apps/{app}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Get OAuth2 application.", - "operationId": "get-oauth2-application", - "parameters": [ - { - "type": "string", - "description": "App ID", - "name": "app", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.OAuth2ProviderApp" - } - } - } - }, - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Update OAuth2 application.", - "operationId": "update-oauth2-application", - "parameters": [ - { - "type": "string", - "description": "App ID", - "name": "app", - "in": "path", - "required": true - }, - { - "description": "Update an OAuth2 application.", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.PutOAuth2ProviderAppRequest" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.OAuth2ProviderApp" - } - } - } - }, - "delete": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "tags": ["Enterprise"], - "summary": "Delete OAuth2 application.", - "operationId": "delete-oauth2-application", - "parameters": [ - { - "type": "string", - "description": "App ID", - "name": "app", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content" - } - } - } - }, - "/oauth2-provider/apps/{app}/secrets": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Get OAuth2 application secrets.", - "operationId": "get-oauth2-application-secrets", - "parameters": [ - { - "type": "string", - "description": "App ID", - "name": "app", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.OAuth2ProviderAppSecret" - } - } - } - } - }, - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Create OAuth2 application secret.", - "operationId": "create-oauth2-application-secret", - "parameters": [ - { - "type": "string", - "description": "App ID", - "name": "app", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.OAuth2ProviderAppSecretFull" - } - } - } - } - } - }, - "/oauth2-provider/apps/{app}/secrets/{secretID}": { - "delete": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "tags": ["Enterprise"], - "summary": "Delete OAuth2 application secret.", - "operationId": "delete-oauth2-application-secret", - "parameters": [ - { - "type": "string", - "description": "App ID", - "name": "app", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Secret ID", - "name": "secretID", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content" - } - } - } - }, - "/oauth2/authorize": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "tags": ["Enterprise"], - "summary": "OAuth2 authorization request.", - "operationId": "oauth2-authorization-request", - "parameters": [ - { - "type": "string", - "description": "Client ID", - "name": "client_id", - "in": "query", - "required": true - }, - { - "type": "string", - "description": "A random unguessable string", - "name": "state", - "in": "query", - "required": true - }, - { - "enum": ["code"], - "type": "string", - "description": "Response type", - "name": "response_type", - "in": "query", - "required": true - }, - { - "type": "string", - "description": "Redirect here after authorization", - "name": "redirect_uri", - "in": "query" - }, - { - "type": "string", - "description": "Token scopes (currently ignored)", - "name": "scope", - "in": "query" - } - ], - "responses": { - "302": { - "description": "Found" - } - } - } - }, - "/oauth2/tokens": { - "post": { - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "OAuth2 token exchange.", - "operationId": "oauth2-token-exchange", - "parameters": [ - { - "type": "string", - "description": "Client ID, required if grant_type=authorization_code", - "name": "client_id", - "in": "formData" - }, - { - "type": "string", - "description": "Client secret, required if grant_type=authorization_code", - "name": "client_secret", - "in": "formData" - }, - { - "type": "string", - "description": "Authorization code, required if grant_type=authorization_code", - "name": "code", - "in": "formData" - }, - { - "type": "string", - "description": "Refresh token, required if grant_type=refresh_token", - "name": "refresh_token", - "in": "formData" - }, - { - "enum": ["authorization_code", "refresh_token"], - "type": "string", - "description": "Grant type", - "name": "grant_type", - "in": "formData", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/oauth2.Token" - } - } - } - }, - "delete": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "tags": ["Enterprise"], - "summary": "Delete OAuth2 application tokens.", - "operationId": "delete-oauth2-application-tokens", - "parameters": [ - { - "type": "string", - "description": "Client ID", - "name": "client_id", - "in": "query", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content" - } - } - } - }, - "/organizations": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Organizations"], - "summary": "Get organizations", - "operationId": "get-organizations", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Organization" - } - } - } - } - }, - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "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/{organization}": { - "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": "organization", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Organization" - } - } - } - }, - "delete": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Organizations"], - "summary": "Delete organization", - "operationId": "delete-organization", - "parameters": [ - { - "type": "string", - "description": "Organization ID or name", - "name": "organization", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - }, - "patch": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Organizations"], - "summary": "Update organization", - "operationId": "update-organization", - "parameters": [ - { - "type": "string", - "description": "Organization ID or name", - "name": "organization", - "in": "path", - "required": true - }, - { - "description": "Patch organization request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateOrganizationRequest" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Organization" - } - } - } - } - }, - "/organizations/{organization}/groups": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Get groups by organization", - "operationId": "get-groups-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.Group" - } - } - } - } - }, - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Create group for organization", - "operationId": "create-group-for-organization", - "parameters": [ - { - "description": "Create group request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.CreateGroupRequest" - } - }, - { - "type": "string", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/codersdk.Group" - } - } - } - } - }, - "/organizations/{organization}/groups/{groupName}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Get group by organization and group name", - "operationId": "get-group-by-organization-and-group-name", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group name", - "name": "groupName", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Group" - } - } - } - } - }, - "/organizations/{organization}/members": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Members"], - "summary": "List organization members", - "operationId": "list-organization-members", - "parameters": [ - { - "type": "string", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.OrganizationMemberWithUserData" - } - } - } - } - } - }, - "/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" - } - } - } - } - }, - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Members"], - "summary": "Upsert a custom organization role", - "operationId": "upsert-a-custom-organization-role", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - }, - { - "description": "Upsert role request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.CustomRoleRequest" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Role" - } - } - } - } - }, - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Members"], - "summary": "Insert a custom organization role", - "operationId": "insert-a-custom-organization-role", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - }, - { - "description": "Insert role request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.CustomRoleRequest" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Role" - } - } - } - } - } - }, - "/organizations/{organization}/members/roles/{roleName}": { - "delete": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Members"], - "summary": "Delete a custom organization role", - "operationId": "delete-a-custom-organization-role", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Role name", - "name": "roleName", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Role" - } - } - } - } - } - }, - "/organizations/{organization}/members/{user}": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Members"], - "summary": "Add organization member", - "operationId": "add-organization-member", - "parameters": [ - { - "type": "string", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.OrganizationMember" - } - } - } - }, - "delete": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "tags": ["Members"], - "summary": "Remove organization member", - "operationId": "remove-organization-member", - "parameters": [ - { - "type": "string", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content" - } - } - } - }, - "/organizations/{organization}/members/{user}/roles": { - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Members"], - "summary": "Assign role to organization member", - "operationId": "assign-role-to-organization-member", - "parameters": [ - { - "type": "string", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - }, - { - "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.OrganizationMember" - } - } - } - } - }, - "/organizations/{organization}/members/{user}/workspaces": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "description": "Create a new workspace using a template. The request must\nspecify either the Template ID or the Template Version ID,\nnot both. If the Template ID is specified, the active version\nof the template will be used.", - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Workspaces"], - "summary": "Create user workspace by organization", - "operationId": "create-user-workspace-by-organization", - "deprecated": true, - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Username, UUID, or me", - "name": "user", - "in": "path", - "required": true - }, - { - "description": "Create workspace request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.CreateWorkspaceRequest" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Workspace" - } - } - } - } - }, - "/organizations/{organization}/provisionerdaemons": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Get provisioner daemons", - "operationId": "get-provisioner-daemons", - "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.ProvisionerDaemon" - } - } - } - } - } - }, - "/organizations/{organization}/provisionerdaemons/serve": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "tags": ["Enterprise"], - "summary": "Serve provisioner daemon", - "operationId": "serve-provisioner-daemon", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - } - ], - "responses": { - "101": { - "description": "Switching Protocols" - } - } - } - }, - "/organizations/{organization}/provisionerkeys": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "List provisioner key", - "operationId": "list-provisioner-key", - "parameters": [ - { - "type": "string", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.ProvisionerKey" - } - } - } - } - }, - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Create provisioner key", - "operationId": "create-provisioner-key", - "parameters": [ - { - "type": "string", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/codersdk.CreateProvisionerKeyResponse" - } - } - } - } - }, - "/organizations/{organization}/provisionerkeys/{provisionerkey}": { - "delete": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "tags": ["Enterprise"], - "summary": "Delete provisioner key", - "operationId": "delete-provisioner-key", - "parameters": [ - { - "type": "string", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Provisioner key name", - "name": "provisionerkey", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content" - } - } - } - }, - "/organizations/{organization}/templates": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Get templates by organization", - "operationId": "get-templates-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.Template" - } - } - } - } - }, - "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", - "deprecated": true, - "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/{templatename}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Get templates by organization and template name", - "operationId": "get-templates-by-organization-and-template-name", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Template name", - "name": "templatename", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Template" - } - } - } - } - }, - "/organizations/{organization}/templates/{templatename}/versions/{templateversionname}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Get template version by organization, template, and name", - "operationId": "get-template-version-by-organization-template-and-name", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Template name", - "name": "templatename", - "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}/templates/{templatename}/versions/{templateversionname}/previous": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Get previous template version by organization, template, and name", - "operationId": "get-previous-template-version-by-organization-template-and-name", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Template name", - "name": "templatename", - "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": { - "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.CreateTemplateVersionRequest" - } - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/codersdk.TemplateVersion" - } - } - } - } - }, - "/regions": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["WorkspaceProxies"], - "summary": "Get site-wide regions for workspace connections", - "operationId": "get-site-wide-regions-for-workspace-connections", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.RegionsResponse-codersdk_Region" - } - } - } - } - }, - "/replicas": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Get active replicas", - "operationId": "get-active-replicas", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Replica" - } - } - } - } - } - }, - "/scim/v2/Users": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/scim+json"], - "tags": ["Enterprise"], - "summary": "SCIM 2.0: Get users", - "operationId": "scim-get-users", - "responses": { - "200": { - "description": "OK" - } - } - }, - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "SCIM 2.0: Create new user", - "operationId": "scim-create-new-user", - "parameters": [ - { - "description": "New user", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/coderd.SCIMUser" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/coderd.SCIMUser" - } - } - } - } - }, - "/scim/v2/Users/{id}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/scim+json"], - "tags": ["Enterprise"], - "summary": "SCIM 2.0: Get user by ID", - "operationId": "scim-get-user-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "User ID", - "name": "id", - "in": "path", - "required": true - } - ], - "responses": { - "404": { - "description": "Not Found" - } - } - }, - "patch": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/scim+json"], - "tags": ["Enterprise"], - "summary": "SCIM 2.0: Update user account", - "operationId": "scim-update-user-status", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "User ID", - "name": "id", - "in": "path", - "required": true - }, - { - "description": "Update user request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/coderd.SCIMUser" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.User" - } - } - } - } - }, - "/templates": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Get all templates", - "operationId": "get-all-templates", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Template" - } - } - } - } - } - }, - "/templates/examples": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Get template examples", - "operationId": "get-template-examples", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.TemplateExample" - } - } - } - } - } - }, - "/templates/{template}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Get template metadata by ID", - "operationId": "get-template-metadata-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template ID", - "name": "template", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Template" - } - } - } - }, - "delete": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Delete template by ID", - "operationId": "delete-template-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template ID", - "name": "template", - "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-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template ID", - "name": "template", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Template" - } - } - } - } - }, - "/templates/{template}/acl": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Get template ACLs", - "operationId": "get-template-acls", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template ID", - "name": "template", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.TemplateUser" - } - } - } - } - }, - "patch": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Update template ACL", - "operationId": "update-template-acl", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template ID", - "name": "template", - "in": "path", - "required": true - }, - { - "description": "Update template request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateTemplateACL" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - } - }, - "/templates/{template}/acl/available": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Get template available acl users/groups", - "operationId": "get-template-available-acl-usersgroups", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template ID", - "name": "template", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.ACLAvailable" - } - } - } - } - } - }, - "/templates/{template}/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": "template", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.DAUsResponse" - } - } - } - } - }, - "/templates/{template}/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": "template", - "in": "path", - "required": true - }, - { - "type": "string", - "format": "uuid", - "description": "After ID", - "name": "after_id", - "in": "query" - }, - { - "type": "boolean", - "description": "Include archived versions in the list", - "name": "include_archived", - "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": { - "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": "template", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - } - }, - "/templates/{template}/versions/archive": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Archive template unused versions by template id", - "operationId": "archive-template-unused-versions-by-template-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template ID", - "name": "template", - "in": "path", - "required": true - }, - { - "description": "Archive request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.ArchiveTemplateVersionsRequest" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - } - }, - "/templates/{template}/versions/{templateversionname}": { - "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": "template", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Template version name", - "name": "templateversionname", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.TemplateVersion" - } - } - } - } - } - }, - "/templateversions/{templateversion}": { - "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": "templateversion", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.TemplateVersion" - } - } - } - }, - "patch": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Patch template version by ID", - "operationId": "patch-template-version-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template version ID", - "name": "templateversion", - "in": "path", - "required": true - }, - { - "description": "Patch template version request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.PatchTemplateVersionRequest" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.TemplateVersion" - } - } - } - } - }, - "/templateversions/{templateversion}/archive": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Archive template version", - "operationId": "archive-template-version", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template version ID", - "name": "templateversion", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - } - }, - "/templateversions/{templateversion}/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": "templateversion", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - } - }, - "/templateversions/{templateversion}/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": "templateversion", - "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/{templateversion}/dry-run/{jobID}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "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": "templateversion", - "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/{templateversion}/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": "Job ID", - "name": "jobID", - "in": "path", - "required": true - }, - { - "type": "string", - "format": "uuid", - "description": "Template version ID", - "name": "templateversion", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - } - }, - "/templateversions/{templateversion}/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": "templateversion", - "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/{templateversion}/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": "templateversion", - "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" - } - } - } - } - } - }, - "/templateversions/{templateversion}/external-auth": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Get external auth by template version", - "operationId": "get-external-auth-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.TemplateVersionExternalAuth" - } - } - } - } - } - }, - "/templateversions/{templateversion}/logs": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Get logs by template version", - "operationId": "get-logs-by-template-version", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template version ID", - "name": "templateversion", - "in": "path", - "required": true - }, - { - "type": "integer", - "description": "Before log id", - "name": "before", - "in": "query" - }, - { - "type": "integer", - "description": "After log id", - "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/{templateversion}/parameters": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "tags": ["Templates"], - "summary": "Removed: Get parameters by template version", - "operationId": "removed-get-parameters-by-template-version", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template version ID", - "name": "templateversion", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK" - } - } - } - }, - "/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": "Template version ID", - "name": "templateversion", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceResource" - } - } - } - } - } - }, - "/templateversions/{templateversion}/rich-parameters": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Get rich parameters by template version", - "operationId": "get-rich-parameters-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.TemplateVersionParameter" - } - } - } - } - } - }, - "/templateversions/{templateversion}/schema": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "tags": ["Templates"], - "summary": "Removed: Get schema by template version", - "operationId": "removed-get-schema-by-template-version", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template version ID", - "name": "templateversion", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK" - } - } - } - }, - "/templateversions/{templateversion}/unarchive": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Unarchive template version", - "operationId": "unarchive-template-version", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template version ID", - "name": "templateversion", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - } - }, - "/templateversions/{templateversion}/variables": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Get template variables by template version", - "operationId": "get-template-variables-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.TemplateVersionVariable" - } - } - } - } - } - }, - "/updatecheck": { - "get": { - "produces": ["application/json"], - "tags": ["General"], - "summary": "Update check", - "operationId": "update-check", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.UpdateCheckResponse" - } - } - } - } - }, - "/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": [ - { - "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": { - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Authorization"], - "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/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": [ - { - "CoderSessionToken": [] - } - ], - "tags": ["Users"], - "summary": "OAuth 2.0 GitHub Callback", - "operationId": "oauth-20-github-callback", - "responses": { - "307": { - "description": "Temporary Redirect" - } - } - } - }, - "/users/oidc/callback": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "tags": ["Users"], - "summary": "OpenID Connect Callback", - "operationId": "openid-connect-callback", - "responses": { - "307": { - "description": "Temporary Redirect" - } - } - } - }, - "/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}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Users"], - "summary": "Get user by name", - "operationId": "get-user-by-name", - "parameters": [ - { - "type": "string", - "description": "User ID, username, or me", - "name": "user", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.User" - } - } - } - }, - "delete": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "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" - } - } - } - }, - "/users/{user}/appearance": { - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Users"], - "summary": "Update user appearance settings", - "operationId": "update-user-appearance-settings", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - }, - { - "description": "New appearance settings", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateUserAppearanceSettingsRequest" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.User" - } - } - } - } - }, - "/users/{user}/autofill-parameters": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Users"], - "summary": "Get autofill build parameters for user", - "operationId": "get-autofill-build-parameters-for-user", - "parameters": [ - { - "type": "string", - "description": "User ID, username, or me", - "name": "user", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Template ID", - "name": "template_id", - "in": "query", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.UserParameter" - } - } - } - } - } - }, - "/users/{user}/convert-login": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Authorization"], - "summary": "Convert user from password to oauth authentication", - "operationId": "convert-user-from-password-to-oauth-authentication", - "parameters": [ - { - "description": "Convert request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.ConvertLoginRequest" - } - }, - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/codersdk.OAuthConversionResponse" - } - } - } - } - }, - "/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": [ - { - "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": [] - } - ], - "consumes": ["application/json"], - "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}/keys/tokens/tokenconfig": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["General"], - "summary": "Get token config", - "operationId": "get-token-config", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.TokenConfig" - } - } - } - } - }, - "/users/{user}/keys/tokens/{keyname}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Users"], - "summary": "Get API key by token name", - "operationId": "get-api-key-by-token-name", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - }, - { - "type": "string", - "format": "string", - "description": "Key Name", - "name": "keyname", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.APIKey" - } - } - } - } - }, - "/users/{user}/keys/{keyid}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Users"], - "summary": "Get API key by ID", - "operationId": "get-api-key-by-id", - "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": [] - } - ], - "tags": ["Users"], - "summary": "Delete API key", - "operationId": "delete-api-key", - "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}/login-type": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Users"], - "summary": "Get user login type", - "operationId": "get-user-login-type", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.UserLoginType" - } - } - } - } - }, - "/users/{user}/notifications/preferences": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Notifications"], - "summary": "Get user notification preferences", - "operationId": "get-user-notification-preferences", - "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.NotificationPreference" - } - } - } - } - }, - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Notifications"], - "summary": "Update user notification preferences", - "operationId": "update-user-notification-preferences", - "parameters": [ - { - "description": "Preferences", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateUserNotificationPreferences" - } - }, - { - "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.NotificationPreference" - } - } - } - } - } - }, - "/users/{user}/organizations": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Users"], - "summary": "Get organizations by user", - "operationId": "get-organizations-by-user", - "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": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["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": { - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "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}/quiet-hours": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Get user quiet hours schedule", - "operationId": "get-user-quiet-hours-schedule", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "User ID", - "name": "user", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.UserQuietHoursScheduleResponse" - } - } - } - } - }, - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Update user quiet hours schedule", - "operationId": "update-user-quiet-hours-schedule", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "User ID", - "name": "user", - "in": "path", - "required": true - }, - { - "description": "Update schedule request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateUserQuietHoursScheduleRequest" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.UserQuietHoursScheduleResponse" - } - } - } - } - } - }, - "/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": [ - { - "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": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Workspaces"], - "summary": "Get workspace metadata by user and workspace name", - "operationId": "get-workspace-metadata-by-user-and-workspace-name", - "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": "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" - } - } - } - } - }, - "/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" - } - } - } - } - }, - "/users/{user}/workspaces": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "description": "Create a new workspace using a template. The request must\nspecify either the Template ID or the Template Version ID,\nnot both. If the Template ID is specified, the active version\nof the template will be used.", - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Workspaces"], - "summary": "Create user workspace", - "operationId": "create-user-workspace", - "parameters": [ - { - "type": "string", - "description": "Username, UUID, or me", - "name": "user", - "in": "path", - "required": true - }, - { - "description": "Create workspace request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.CreateWorkspaceRequest" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Workspace" - } - } - } - } - }, - "/workspace-quota/{user}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Get workspace quota by user", - "operationId": "get-workspace-quota-by-user", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.WorkspaceQuota" - } - } - } - } - }, - "/workspaceagents/aws-instance-identity": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Agents"], - "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/agentsdk.AWSInstanceIdentityToken" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/agentsdk.AuthenticateResponse" - } - } - } - } - }, - "/workspaceagents/azure-instance-identity": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Agents"], - "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/agentsdk.AzureInstanceIdentityToken" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/agentsdk.AuthenticateResponse" - } - } - } - } - }, - "/workspaceagents/connection": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Agents"], - "summary": "Get connection info for workspace agent generic", - "operationId": "get-connection-info-for-workspace-agent-generic", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/workspacesdk.AgentConnectionInfo" - } - } - }, - "x-apidocgen": { - "skip": true - } - } - }, - "/workspaceagents/google-instance-identity": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Agents"], - "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/agentsdk.GoogleInstanceIdentityToken" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/agentsdk.AuthenticateResponse" - } - } - } - } - }, - "/workspaceagents/me/external-auth": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Agents"], - "summary": "Get workspace agent external auth", - "operationId": "get-workspace-agent-external-auth", - "parameters": [ - { - "type": "string", - "description": "Match", - "name": "match", - "in": "query", - "required": true - }, - { - "type": "string", - "description": "Provider ID", - "name": "id", - "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/agentsdk.ExternalAuthResponse" - } - } - } - } - }, - "/workspaceagents/me/gitauth": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Agents"], - "summary": "Removed: Get workspace agent git auth", - "operationId": "removed-get-workspace-agent-git-auth", - "parameters": [ - { - "type": "string", - "description": "Match", - "name": "match", - "in": "query", - "required": true - }, - { - "type": "string", - "description": "Provider ID", - "name": "id", - "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/agentsdk.ExternalAuthResponse" - } - } - } - } - }, - "/workspaceagents/me/gitsshkey": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "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/agentsdk.GitSSHKey" - } - } - } - } - }, - "/workspaceagents/me/log-source": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Agents"], - "summary": "Post workspace agent log source", - "operationId": "post-workspace-agent-log-source", - "parameters": [ - { - "description": "Log source request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/agentsdk.PostLogSourceRequest" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.WorkspaceAgentLogSource" - } - } - } - } - }, - "/workspaceagents/me/logs": { - "patch": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Agents"], - "summary": "Patch workspace agent logs", - "operationId": "patch-workspace-agent-logs", - "parameters": [ - { - "description": "logs", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/agentsdk.PatchLogs" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - } - }, - "/workspaceagents/me/rpc": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "tags": ["Agents"], - "summary": "Workspace agent RPC API", - "operationId": "workspace-agent-rpc-api", - "responses": { - "101": { - "description": "Switching Protocols" - } - }, - "x-apidocgen": { - "skip": true - } - } - }, - "/workspaceagents/{workspaceagent}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Agents"], - "summary": "Get workspace agent by ID", - "operationId": "get-workspace-agent-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace agent ID", - "name": "workspaceagent", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.WorkspaceAgent" - } - } - } - } - }, - "/workspaceagents/{workspaceagent}/connection": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Agents"], - "summary": "Get connection info for workspace agent", - "operationId": "get-connection-info-for-workspace-agent", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace agent ID", - "name": "workspaceagent", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/workspacesdk.AgentConnectionInfo" - } - } - } - } - }, - "/workspaceagents/{workspaceagent}/coordinate": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "tags": ["Agents"], - "summary": "Coordinate workspace agent", - "operationId": "coordinate-workspace-agent", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace agent ID", - "name": "workspaceagent", - "in": "path", - "required": true - } - ], - "responses": { - "101": { - "description": "Switching Protocols" - } - } - } - }, - "/workspaceagents/{workspaceagent}/listening-ports": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Agents"], - "summary": "Get listening ports for workspace agent", - "operationId": "get-listening-ports-for-workspace-agent", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace agent ID", - "name": "workspaceagent", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.WorkspaceAgentListeningPortsResponse" - } - } - } - } - }, - "/workspaceagents/{workspaceagent}/logs": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Agents"], - "summary": "Get logs by workspace agent", - "operationId": "get-logs-by-workspace-agent", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace agent ID", - "name": "workspaceagent", - "in": "path", - "required": true - }, - { - "type": "integer", - "description": "Before log id", - "name": "before", - "in": "query" - }, - { - "type": "integer", - "description": "After log id", - "name": "after", - "in": "query" - }, - { - "type": "boolean", - "description": "Follow log stream", - "name": "follow", - "in": "query" - }, - { - "type": "boolean", - "description": "Disable compression for WebSocket connection", - "name": "no_compression", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceAgentLog" - } - } - } - } - } - }, - "/workspaceagents/{workspaceagent}/pty": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "tags": ["Agents"], - "summary": "Open PTY to workspace agent", - "operationId": "open-pty-to-workspace-agent", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace agent ID", - "name": "workspaceagent", - "in": "path", - "required": true - } - ], - "responses": { - "101": { - "description": "Switching Protocols" - } - } - } - }, - "/workspaceagents/{workspaceagent}/startup-logs": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Agents"], - "summary": "Removed: Get logs by workspace agent", - "operationId": "removed-get-logs-by-workspace-agent", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace agent ID", - "name": "workspaceagent", - "in": "path", - "required": true - }, - { - "type": "integer", - "description": "Before log id", - "name": "before", - "in": "query" - }, - { - "type": "integer", - "description": "After log id", - "name": "after", - "in": "query" - }, - { - "type": "boolean", - "description": "Follow log stream", - "name": "follow", - "in": "query" - }, - { - "type": "boolean", - "description": "Disable compression for WebSocket connection", - "name": "no_compression", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceAgentLog" - } - } - } - } - } - }, - "/workspaceagents/{workspaceagent}/watch-metadata": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "tags": ["Agents"], - "summary": "Watch for workspace agent metadata updates", - "operationId": "watch-for-workspace-agent-metadata-updates", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace agent ID", - "name": "workspaceagent", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "Success" - } - }, - "x-apidocgen": { - "skip": true - } - } - }, - "/workspacebuilds/{workspacebuild}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Builds"], - "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": ["Builds"], - "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": ["Builds"], - "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}/parameters": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Builds"], - "summary": "Get build parameters for workspace build", - "operationId": "get-build-parameters-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.WorkspaceBuildParameter" - } - } - } - } - } - }, - "/workspacebuilds/{workspacebuild}/resources": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Builds"], - "summary": "Removed: Get workspace resources for workspace build", - "operationId": "removed-get-workspace-resources-for-workspace-build", - "deprecated": true, - "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": ["Builds"], - "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" - } - } - } - } - }, - "/workspaceproxies": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Get workspace proxies", - "operationId": "get-workspace-proxies", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.RegionsResponse-codersdk_WorkspaceProxy" - } - } - } - } - }, - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Create workspace proxy", - "operationId": "create-workspace-proxy", - "parameters": [ - { - "description": "Create workspace proxy request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.CreateWorkspaceProxyRequest" - } - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/codersdk.WorkspaceProxy" - } - } - } - } - }, - "/workspaceproxies/me/app-stats": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "tags": ["Enterprise"], - "summary": "Report workspace app stats", - "operationId": "report-workspace-app-stats", - "parameters": [ - { - "description": "Report app stats request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/wsproxysdk.ReportAppStatsRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - } - }, - "x-apidocgen": { - "skip": true - } - } - }, - "/workspaceproxies/me/coordinate": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "tags": ["Enterprise"], - "summary": "Workspace Proxy Coordinate", - "operationId": "workspace-proxy-coordinate", - "responses": { - "101": { - "description": "Switching Protocols" - } - }, - "x-apidocgen": { - "skip": true - } - } - }, - "/workspaceproxies/me/deregister": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "tags": ["Enterprise"], - "summary": "Deregister workspace proxy", - "operationId": "deregister-workspace-proxy", - "parameters": [ - { - "description": "Deregister workspace proxy request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/wsproxysdk.DeregisterWorkspaceProxyRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - } - }, - "x-apidocgen": { - "skip": true - } - } - }, - "/workspaceproxies/me/issue-signed-app-token": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Issue signed workspace app token", - "operationId": "issue-signed-workspace-app-token", - "parameters": [ - { - "description": "Issue signed app token request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/workspaceapps.IssueTokenRequest" - } - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/wsproxysdk.IssueSignedAppTokenResponse" - } - } - }, - "x-apidocgen": { - "skip": true - } - } - }, - "/workspaceproxies/me/register": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Register workspace proxy", - "operationId": "register-workspace-proxy", - "parameters": [ - { - "description": "Register workspace proxy request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/wsproxysdk.RegisterWorkspaceProxyRequest" - } - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/wsproxysdk.RegisterWorkspaceProxyResponse" - } - } - }, - "x-apidocgen": { - "skip": true - } - } - }, - "/workspaceproxies/{workspaceproxy}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Get workspace proxy", - "operationId": "get-workspace-proxy", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Proxy ID or name", - "name": "workspaceproxy", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.WorkspaceProxy" - } - } - } - }, - "delete": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Delete workspace proxy", - "operationId": "delete-workspace-proxy", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Proxy ID or name", - "name": "workspaceproxy", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - }, - "patch": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Update workspace proxy", - "operationId": "update-workspace-proxy", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Proxy ID or name", - "name": "workspaceproxy", - "in": "path", - "required": true - }, - { - "description": "Update workspace proxy request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.PatchWorkspaceProxy" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.WorkspaceProxy" - } - } - } - } - }, - "/workspaces": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Workspaces"], - "summary": "List workspaces", - "operationId": "list-workspaces", - "parameters": [ - { - "type": "string", - "description": "Search query in the format `key:value`. Available keys are: owner, template, name, status, has-agent, dormant, last_used_after, last_used_before.", - "name": "q", - "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.WorkspacesResponse" - } - } - } - } - }, - "/workspaces/{workspace}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Workspaces"], - "summary": "Get workspace metadata by ID", - "operationId": "get-workspace-metadata-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace ID", - "name": "workspace", - "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" - } - } - } - }, - "patch": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "tags": ["Workspaces"], - "summary": "Update workspace metadata by ID", - "operationId": "update-workspace-metadata-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace ID", - "name": "workspace", - "in": "path", - "required": true - }, - { - "description": "Metadata update request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateWorkspaceRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - } - } - } - }, - "/workspaces/{workspace}/autostart": { - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "tags": ["Workspaces"], - "summary": "Update workspace autostart schedule by ID", - "operationId": "update-workspace-autostart-schedule-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace ID", - "name": "workspace", - "in": "path", - "required": true - }, - { - "description": "Schedule update request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateWorkspaceAutostartRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - } - } - } - }, - "/workspaces/{workspace}/autoupdates": { - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "tags": ["Workspaces"], - "summary": "Update workspace automatic updates by ID", - "operationId": "update-workspace-automatic-updates-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace ID", - "name": "workspace", - "in": "path", - "required": true - }, - { - "description": "Automatic updates request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateWorkspaceAutomaticUpdatesRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - } - } - } - }, - "/workspaces/{workspace}/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": "workspace", - "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": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Builds"], - "summary": "Create workspace build", - "operationId": "create-workspace-build", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace ID", - "name": "workspace", - "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}/dormant": { - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Workspaces"], - "summary": "Update workspace dormancy status by id.", - "operationId": "update-workspace-dormancy-status-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace ID", - "name": "workspace", - "in": "path", - "required": true - }, - { - "description": "Make a workspace dormant or active", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateWorkspaceDormancy" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Workspace" - } - } - } - } - }, - "/workspaces/{workspace}/extend": { - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Workspaces"], - "summary": "Extend workspace deadline by ID", - "operationId": "extend-workspace-deadline-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace ID", - "name": "workspace", - "in": "path", - "required": true - }, - { - "description": "Extend deadline update request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.PutExtendWorkspaceRequest" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - } - }, - "/workspaces/{workspace}/favorite": { - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "tags": ["Workspaces"], - "summary": "Favorite workspace by ID.", - "operationId": "favorite-workspace-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace ID", - "name": "workspace", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content" - } - } - }, - "delete": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "tags": ["Workspaces"], - "summary": "Unfavorite workspace by ID.", - "operationId": "unfavorite-workspace-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace ID", - "name": "workspace", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content" - } - } - } - }, - "/workspaces/{workspace}/port-share": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["PortSharing"], - "summary": "Get workspace agent port shares", - "operationId": "get-workspace-agent-port-shares", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace ID", - "name": "workspace", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.WorkspaceAgentPortShares" - } - } - } - }, - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["PortSharing"], - "summary": "Upsert workspace agent port share", - "operationId": "upsert-workspace-agent-port-share", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace ID", - "name": "workspace", - "in": "path", - "required": true - }, - { - "description": "Upsert port sharing level request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpsertWorkspaceAgentPortShareRequest" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.WorkspaceAgentPortShare" - } - } - } - }, - "delete": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "tags": ["PortSharing"], - "summary": "Get workspace agent port shares", - "operationId": "get-workspace-agent-port-shares", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace ID", - "name": "workspace", - "in": "path", - "required": true - }, - { - "description": "Delete port sharing level request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.DeleteWorkspaceAgentPortShareRequest" - } - } - ], - "responses": { - "200": { - "description": "OK" - } - } - } - }, - "/workspaces/{workspace}/resolve-autostart": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Workspaces"], - "summary": "Resolve workspace autostart by id.", - "operationId": "resolve-workspace-autostart-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace ID", - "name": "workspace", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.ResolveAutostartResponse" - } - } - } - } - }, - "/workspaces/{workspace}/ttl": { - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "tags": ["Workspaces"], - "summary": "Update workspace TTL by ID", - "operationId": "update-workspace-ttl-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace ID", - "name": "workspace", - "in": "path", - "required": true - }, - { - "description": "Workspace TTL update request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateWorkspaceTTLRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - } - } - } - }, - "/workspaces/{workspace}/usage": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "tags": ["Workspaces"], - "summary": "Post Workspace Usage by ID", - "operationId": "post-workspace-usage-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace ID", - "name": "workspace", - "in": "path", - "required": true - }, - { - "description": "Post workspace usage request", - "name": "request", - "in": "body", - "schema": { - "$ref": "#/definitions/codersdk.PostWorkspaceUsageRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - } - } - } - }, - "/workspaces/{workspace}/watch": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["text/event-stream"], - "tags": ["Workspaces"], - "summary": "Watch workspace by ID", - "operationId": "watch-workspace-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace ID", - "name": "workspace", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - } - } - }, - "definitions": { - "agentsdk.AWSInstanceIdentityToken": { - "type": "object", - "required": ["document", "signature"], - "properties": { - "document": { - "type": "string" - }, - "signature": { - "type": "string" - } - } - }, - "agentsdk.AuthenticateResponse": { - "type": "object", - "properties": { - "session_token": { - "type": "string" - } - } - }, - "agentsdk.AzureInstanceIdentityToken": { - "type": "object", - "required": ["encoding", "signature"], - "properties": { - "encoding": { - "type": "string" - }, - "signature": { - "type": "string" - } - } - }, - "agentsdk.ExternalAuthResponse": { - "type": "object", - "properties": { - "access_token": { - "type": "string" - }, - "password": { - "type": "string" - }, - "token_extra": { - "type": "object", - "additionalProperties": true - }, - "type": { - "type": "string" - }, - "url": { - "type": "string" - }, - "username": { - "description": "Deprecated: Only supported on `/workspaceagents/me/gitauth`\nfor backwards compatibility.", - "type": "string" - } - } - }, - "agentsdk.GitSSHKey": { - "type": "object", - "properties": { - "private_key": { - "type": "string" - }, - "public_key": { - "type": "string" - } - } - }, - "agentsdk.GoogleInstanceIdentityToken": { - "type": "object", - "required": ["json_web_token"], - "properties": { - "json_web_token": { - "type": "string" - } - } - }, - "agentsdk.Log": { - "type": "object", - "properties": { - "created_at": { - "type": "string" - }, - "level": { - "$ref": "#/definitions/codersdk.LogLevel" - }, - "output": { - "type": "string" - } - } - }, - "agentsdk.PatchLogs": { - "type": "object", - "properties": { - "log_source_id": { - "type": "string" - }, - "logs": { - "type": "array", - "items": { - "$ref": "#/definitions/agentsdk.Log" - } - } - } - }, - "agentsdk.PostLogSourceRequest": { - "type": "object", - "properties": { - "display_name": { - "type": "string" - }, - "icon": { - "type": "string" - }, - "id": { - "description": "ID is a unique identifier for the log source.\nIt is scoped to a workspace agent, and can be statically\ndefined inside code to prevent duplicate sources from being\ncreated for the same agent.", - "type": "string" - } - } - }, - "coderd.SCIMUser": { - "type": "object", - "properties": { - "active": { - "type": "boolean" - }, - "emails": { - "type": "array", - "items": { - "type": "object", - "properties": { - "display": { - "type": "string" - }, - "primary": { - "type": "boolean" - }, - "type": { - "type": "string" - }, - "value": { - "type": "string", - "format": "email" - } - } - } - }, - "groups": { - "type": "array", - "items": {} - }, - "id": { - "type": "string" - }, - "meta": { - "type": "object", - "properties": { - "resourceType": { - "type": "string" - } - } - }, - "name": { - "type": "object", - "properties": { - "familyName": { - "type": "string" - }, - "givenName": { - "type": "string" - } - } - }, - "schemas": { - "type": "array", - "items": { - "type": "string" - } - }, - "userName": { - "type": "string" - } - } - }, - "coderd.cspViolation": { - "type": "object", - "properties": { - "csp-report": { - "type": "object", - "additionalProperties": true - } - } - }, - "codersdk.ACLAvailable": { - "type": "object", - "properties": { - "groups": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Group" - } - }, - "users": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.ReducedUser" - } - } - } - }, - "codersdk.APIKey": { - "type": "object", - "required": [ - "created_at", - "expires_at", - "id", - "last_used", - "lifetime_seconds", - "login_type", - "scope", - "token_name", - "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": { - "enum": ["password", "github", "oidc", "token"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.LoginType" - } - ] - }, - "scope": { - "enum": ["all", "application_connect"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.APIKeyScope" - } - ] - }, - "token_name": { - "type": "string" - }, - "updated_at": { - "type": "string", - "format": "date-time" - }, - "user_id": { - "type": "string", - "format": "uuid" - } - } - }, - "codersdk.APIKeyScope": { - "type": "string", - "enum": ["all", "application_connect"], - "x-enum-varnames": ["APIKeyScopeAll", "APIKeyScopeApplicationConnect"] - }, - "codersdk.AddLicenseRequest": { - "type": "object", - "required": ["license"], - "properties": { - "license": { - "type": "string" - } - } - }, - "codersdk.AgentSubsystem": { - "type": "string", - "enum": ["envbox", "envbuilder", "exectrace"], - "x-enum-varnames": [ - "AgentSubsystemEnvbox", - "AgentSubsystemEnvbuilder", - "AgentSubsystemExectrace" - ] - }, - "codersdk.AppHostResponse": { - "type": "object", - "properties": { - "host": { - "description": "Host is the externally accessible URL for the Coder instance.", - "type": "string" - } - } - }, - "codersdk.AppearanceConfig": { - "type": "object", - "properties": { - "announcement_banners": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.BannerConfig" - } - }, - "application_name": { - "type": "string" - }, - "logo_url": { - "type": "string" - }, - "service_banner": { - "description": "Deprecated: ServiceBanner has been replaced by AnnouncementBanners.", - "allOf": [ - { - "$ref": "#/definitions/codersdk.BannerConfig" - } - ] - }, - "support_links": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.LinkConfig" - } - } - } - }, - "codersdk.ArchiveTemplateVersionsRequest": { - "type": "object", - "properties": { - "all": { - "description": "By default, only failed versions are archived. Set this to true\nto archive all unused versions regardless of job status.", - "type": "boolean" - } - } - }, - "codersdk.AssignableRoles": { - "type": "object", - "properties": { - "assignable": { - "type": "boolean" - }, - "built_in": { - "description": "BuiltIn roles are immutable", - "type": "boolean" - }, - "display_name": { - "type": "string" - }, - "name": { - "type": "string" - }, - "organization_id": { - "type": "string", - "format": "uuid" - }, - "organization_permissions": { - "description": "OrganizationPermissions are specific for the organization in the field 'OrganizationID' above.", - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Permission" - } - }, - "site_permissions": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Permission" - } - }, - "user_permissions": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Permission" - } - } - } - }, - "codersdk.AuditAction": { - "type": "string", - "enum": [ - "create", - "write", - "delete", - "start", - "stop", - "login", - "logout", - "register" - ], - "x-enum-varnames": [ - "AuditActionCreate", - "AuditActionWrite", - "AuditActionDelete", - "AuditActionStart", - "AuditActionStop", - "AuditActionLogin", - "AuditActionLogout", - "AuditActionRegister" - ] - }, - "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": { - "$ref": "#/definitions/codersdk.AuditAction" - }, - "additional_fields": { - "type": "array", - "items": { - "type": "integer" - } - }, - "description": { - "type": "string" - }, - "diff": { - "$ref": "#/definitions/codersdk.AuditDiff" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "ip": { - "type": "string" - }, - "is_deleted": { - "type": "boolean" - }, - "organization": { - "$ref": "#/definitions/codersdk.MinimalOrganization" - }, - "organization_id": { - "description": "Deprecated: Use 'organization.id' instead.", - "type": "string", - "format": "uuid" - }, - "request_id": { - "type": "string", - "format": "uuid" - }, - "resource_icon": { - "type": "string" - }, - "resource_id": { - "type": "string", - "format": "uuid" - }, - "resource_link": { - "type": "string" - }, - "resource_target": { - "description": "ResourceTarget is the name of the resource.", - "type": "string" - }, - "resource_type": { - "$ref": "#/definitions/codersdk.ResourceType" - }, - "status_code": { - "type": "integer" - }, - "time": { - "type": "string", - "format": "date-time" - }, - "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.AuthMethod": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - } - } - }, - "codersdk.AuthMethods": { - "type": "object", - "properties": { - "github": { - "$ref": "#/definitions/codersdk.AuthMethod" - }, - "oidc": { - "$ref": "#/definitions/codersdk.OIDCAuthMethod" - }, - "password": { - "$ref": "#/definitions/codersdk.AuthMethod" - }, - "terms_of_service_url": { - "type": "string" - } - } - }, - "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": { - "enum": ["create", "read", "update", "delete"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.RBACAction" - } - ] - }, - "object": { - "description": "Object can represent a \"set\" of objects, such as: all workspaces in an organization, all workspaces owned by me, and all workspaces across the entire product.\nWhen defining an object, use the most specific language when possible to\nproduce the smallest set. Meaning to set as many fields on 'Object' as\nyou can. Example, if you want to check if you can update all workspaces\nowned by 'me', try to also add an 'OrganizationID' to the settings.\nOmitting the 'OrganizationID' could produce the incorrect value, as\nworkspaces have both `user` and `organization` owners.", - "allOf": [ - { - "$ref": "#/definitions/codersdk.AuthorizationObject" - } - ] - } - } - }, - "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": { - "any_org": { - "description": "AnyOrgOwner (optional) will disregard the org_owner when checking for permissions.\nThis cannot be set to true if the OrganizationID is set.", - "type": "boolean" - }, - "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.", - "allOf": [ - { - "$ref": "#/definitions/codersdk.RBACResource" - } - ] - } - } - }, - "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.AutomaticUpdates": { - "type": "string", - "enum": ["always", "never"], - "x-enum-varnames": ["AutomaticUpdatesAlways", "AutomaticUpdatesNever"] - }, - "codersdk.BannerConfig": { - "type": "object", - "properties": { - "background_color": { - "type": "string" - }, - "enabled": { - "type": "boolean" - }, - "message": { - "type": "string" - } - } - }, - "codersdk.BuildInfoResponse": { - "type": "object", - "properties": { - "agent_api_version": { - "description": "AgentAPIVersion is the current version of the Agent API (back versions\nMAY still be supported).", - "type": "string" - }, - "dashboard_url": { - "description": "DashboardURL is the URL to hit the deployment's dashboard.\nFor external workspace proxies, this is the coderd they are connected\nto.", - "type": "string" - }, - "deployment_id": { - "description": "DeploymentID is the unique identifier for this deployment.", - "type": "string" - }, - "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" - }, - "telemetry": { - "description": "Telemetry is a boolean that indicates whether telemetry is enabled.", - "type": "boolean" - }, - "upgrade_message": { - "description": "UpgradeMessage is the message displayed to users when an outdated client\nis detected.", - "type": "string" - }, - "version": { - "description": "Version returns the semantic version of the build.", - "type": "string" - }, - "workspace_proxy": { - "type": "boolean" - } - } - }, - "codersdk.BuildReason": { - "type": "string", - "enum": ["initiator", "autostart", "autostop"], - "x-enum-varnames": [ - "BuildReasonInitiator", - "BuildReasonAutostart", - "BuildReasonAutostop" - ] - }, - "codersdk.ConnectionLatency": { - "type": "object", - "properties": { - "p50": { - "type": "number", - "example": 31.312 - }, - "p95": { - "type": "number", - "example": 119.832 - } - } - }, - "codersdk.ConvertLoginRequest": { - "type": "object", - "required": ["password", "to_type"], - "properties": { - "password": { - "type": "string" - }, - "to_type": { - "description": "ToType is the login type to convert to.", - "allOf": [ - { - "$ref": "#/definitions/codersdk.LoginType" - } - ] - } - } - }, - "codersdk.CreateFirstUserRequest": { - "type": "object", - "required": ["email", "password", "username"], - "properties": { - "email": { - "type": "string" - }, - "name": { - "type": "string" - }, - "password": { - "type": "string" - }, - "trial": { - "type": "boolean" - }, - "trial_info": { - "$ref": "#/definitions/codersdk.CreateFirstUserTrialInfo" - }, - "username": { - "type": "string" - } - } - }, - "codersdk.CreateFirstUserResponse": { - "type": "object", - "properties": { - "organization_id": { - "type": "string", - "format": "uuid" - }, - "user_id": { - "type": "string", - "format": "uuid" - } - } - }, - "codersdk.CreateFirstUserTrialInfo": { - "type": "object", - "properties": { - "company_name": { - "type": "string" - }, - "country": { - "type": "string" - }, - "developers": { - "type": "string" - }, - "first_name": { - "type": "string" - }, - "job_title": { - "type": "string" - }, - "last_name": { - "type": "string" - }, - "phone_number": { - "type": "string" - } - } - }, - "codersdk.CreateGroupRequest": { - "type": "object", - "required": ["name"], - "properties": { - "avatar_url": { - "type": "string" - }, - "display_name": { - "type": "string" - }, - "name": { - "type": "string" - }, - "quota_allowance": { - "type": "integer" - } - } - }, - "codersdk.CreateOrganizationRequest": { - "type": "object", - "required": ["name"], - "properties": { - "description": { - "type": "string" - }, - "display_name": { - "description": "DisplayName will default to the same value as `Name` if not provided.", - "type": "string" - }, - "icon": { - "type": "string" - }, - "name": { - "type": "string" - } - } - }, - "codersdk.CreateProvisionerKeyResponse": { - "type": "object", - "properties": { - "key": { - "type": "string" - } - } - }, - "codersdk.CreateTemplateRequest": { - "type": "object", - "required": ["name", "template_version_id"], - "properties": { - "activity_bump_ms": { - "description": "ActivityBumpMillis allows optionally specifying the activity bump\nduration for all workspaces created from this template. Defaults to 1h\nbut can be set to 0 to disable activity bumping.", - "type": "integer" - }, - "allow_user_autostart": { - "description": "AllowUserAutostart allows users to set a schedule for autostarting their\nworkspace. By default this is true. This can only be disabled when using\nan enterprise license.", - "type": "boolean" - }, - "allow_user_autostop": { - "description": "AllowUserAutostop allows users to set a custom workspace TTL to use in\nplace of the template's DefaultTTL field. By default this is true. If\nfalse, the DefaultTTL will always be used. This can only be disabled when\nusing an enterprise license.", - "type": "boolean" - }, - "allow_user_cancel_workspace_jobs": { - "description": "Allow users to cancel in-progress workspace jobs.\n*bool as the default value is \"true\".", - "type": "boolean" - }, - "autostart_requirement": { - "description": "AutostartRequirement allows optionally specifying the autostart allowed days\nfor workspaces created from this template. This is an enterprise feature.", - "allOf": [ - { - "$ref": "#/definitions/codersdk.TemplateAutostartRequirement" - } - ] - }, - "autostop_requirement": { - "description": "AutostopRequirement allows optionally specifying the autostop requirement\nfor workspaces created from this template. This is an enterprise feature.", - "allOf": [ - { - "$ref": "#/definitions/codersdk.TemplateAutostopRequirement" - } - ] - }, - "default_ttl_ms": { - "description": "DefaultTTLMillis allows optionally specifying the default TTL\nfor all workspaces created from this template.", - "type": "integer" - }, - "delete_ttl_ms": { - "description": "TimeTilDormantAutoDeleteMillis allows optionally specifying the max lifetime before Coder\npermanently deletes dormant 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" - }, - "disable_everyone_group_access": { - "description": "DisableEveryoneGroupAccess allows optionally disabling the default\nbehavior of granting the 'everyone' group access to use the template.\nIf this is set to true, the template will not be available to all users,\nand must be explicitly granted to users or groups in the permissions settings\nof the template.", - "type": "boolean" - }, - "display_name": { - "description": "DisplayName is the displayed name of the template.", - "type": "string" - }, - "dormant_ttl_ms": { - "description": "TimeTilDormantMillis allows optionally specifying the max lifetime before Coder\nlocks inactive workspaces created from this template.", - "type": "integer" - }, - "failure_ttl_ms": { - "description": "FailureTTLMillis allows optionally specifying the max lifetime before Coder\nstops all resources for failed workspaces created from this template.", - "type": "integer" - }, - "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" - }, - "require_active_version": { - "description": "RequireActiveVersion mandates that workspaces are built with the active\ntemplate version.", - "type": "boolean" - }, - "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", - "format": "uuid" - } - } - }, - "codersdk.CreateTemplateVersionDryRunRequest": { - "type": "object", - "properties": { - "rich_parameter_values": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceBuildParameter" - } - }, - "user_variable_values": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.VariableValue" - } - }, - "workspace_name": { - "type": "string" - } - } - }, - "codersdk.CreateTemplateVersionRequest": { - "type": "object", - "required": ["provisioner", "storage_method"], - "properties": { - "example_id": { - "type": "string" - }, - "file_id": { - "type": "string", - "format": "uuid" - }, - "message": { - "type": "string" - }, - "name": { - "type": "string" - }, - "provisioner": { - "type": "string", - "enum": ["terraform", "echo"] - }, - "storage_method": { - "enum": ["file"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.ProvisionerStorageMethod" - } - ] - }, - "tags": { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "template_id": { - "description": "TemplateID optionally associates a version with a template.", - "type": "string", - "format": "uuid" - }, - "user_variable_values": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.VariableValue" - } - } - } - }, - "codersdk.CreateTestAuditLogRequest": { - "type": "object", - "properties": { - "action": { - "enum": ["create", "write", "delete", "start", "stop"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.AuditAction" - } - ] - }, - "additional_fields": { - "type": "array", - "items": { - "type": "integer" - } - }, - "build_reason": { - "enum": ["autostart", "autostop", "initiator"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.BuildReason" - } - ] - }, - "organization_id": { - "type": "string", - "format": "uuid" - }, - "resource_id": { - "type": "string", - "format": "uuid" - }, - "resource_type": { - "enum": [ - "template", - "template_version", - "user", - "workspace", - "workspace_build", - "git_ssh_key", - "auditable_group" - ], - "allOf": [ - { - "$ref": "#/definitions/codersdk.ResourceType" - } - ] - }, - "time": { - "type": "string", - "format": "date-time" - } - } - }, - "codersdk.CreateTokenRequest": { - "type": "object", - "properties": { - "lifetime": { - "type": "integer" - }, - "scope": { - "enum": ["all", "application_connect"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.APIKeyScope" - } - ] - }, - "token_name": { - "type": "string" - } - } - }, - "codersdk.CreateUserRequest": { - "type": "object", - "required": ["email", "username"], - "properties": { - "disable_login": { - "description": "DisableLogin sets the user's login type to 'none'. This prevents the user\nfrom being able to use a password or any other authentication method to login.\nDeprecated: Set UserLoginType=LoginTypeDisabled instead.", - "type": "boolean" - }, - "email": { - "type": "string", - "format": "email" - }, - "login_type": { - "description": "UserLoginType defaults to LoginTypePassword.", - "allOf": [ - { - "$ref": "#/definitions/codersdk.LoginType" - } - ] - }, - "name": { - "type": "string" - }, - "organization_id": { - "type": "string", - "format": "uuid" - }, - "password": { - "type": "string" - }, - "username": { - "type": "string" - } - } - }, - "codersdk.CreateWorkspaceBuildRequest": { - "type": "object", - "required": ["transition"], - "properties": { - "dry_run": { - "type": "boolean" - }, - "log_level": { - "description": "Log level changes the default logging verbosity of a provider (\"info\" if empty).", - "enum": ["debug"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.ProvisionerLogLevel" - } - ] - }, - "orphan": { - "description": "Orphan may be set for the Destroy transition.", - "type": "boolean" - }, - "rich_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.WorkspaceBuildParameter" - } - }, - "state": { - "type": "array", - "items": { - "type": "integer" - } - }, - "template_version_id": { - "type": "string", - "format": "uuid" - }, - "transition": { - "enum": ["create", "start", "stop", "delete"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.WorkspaceTransition" - } - ] - } - } - }, - "codersdk.CreateWorkspaceProxyRequest": { - "type": "object", - "required": ["name"], - "properties": { - "display_name": { - "type": "string" - }, - "icon": { - "type": "string" - }, - "name": { - "type": "string" - } - } - }, - "codersdk.CreateWorkspaceRequest": { - "description": "CreateWorkspaceRequest provides options for creating a new workspace. Only one of TemplateID or TemplateVersionID can be specified, not both. If TemplateID is specified, the active version of the template will be used.", - "type": "object", - "required": ["name"], - "properties": { - "automatic_updates": { - "$ref": "#/definitions/codersdk.AutomaticUpdates" - }, - "autostart_schedule": { - "type": "string" - }, - "name": { - "type": "string" - }, - "rich_parameter_values": { - "description": "RichParameterValues allows for additional parameters to be provided\nduring the initial provision.", - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceBuildParameter" - } - }, - "template_id": { - "description": "TemplateID specifies which template should be used for creating the workspace.", - "type": "string", - "format": "uuid" - }, - "template_version_id": { - "description": "TemplateVersionID can be used to specify a specific version of a template for creating the workspace.", - "type": "string", - "format": "uuid" - }, - "ttl_ms": { - "type": "integer" - } - } - }, - "codersdk.CustomRoleRequest": { - "type": "object", - "properties": { - "display_name": { - "type": "string" - }, - "name": { - "type": "string" - }, - "organization_permissions": { - "description": "OrganizationPermissions are specific to the organization the role belongs to.", - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Permission" - } - }, - "site_permissions": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Permission" - } - }, - "user_permissions": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Permission" - } - } - } - }, - "codersdk.DAUEntry": { - "type": "object", - "properties": { - "amount": { - "type": "integer" - }, - "date": { - "description": "Date is a string formatted as 2024-01-31.\nTimezone and time information is not included.", - "type": "string" - } - } - }, - "codersdk.DAUsResponse": { - "type": "object", - "properties": { - "entries": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.DAUEntry" - } - }, - "tz_hour_offset": { - "type": "integer" - } - } - }, - "codersdk.DERP": { - "type": "object", - "properties": { - "config": { - "$ref": "#/definitions/codersdk.DERPConfig" - }, - "server": { - "$ref": "#/definitions/codersdk.DERPServerConfig" - } - } - }, - "codersdk.DERPConfig": { - "type": "object", - "properties": { - "block_direct": { - "type": "boolean" - }, - "force_websockets": { - "type": "boolean" - }, - "path": { - "type": "string" - }, - "url": { - "type": "string" - } - } - }, - "codersdk.DERPRegion": { - "type": "object", - "properties": { - "latency_ms": { - "type": "number" - }, - "preferred": { - "type": "boolean" - } - } - }, - "codersdk.DERPServerConfig": { - "type": "object", - "properties": { - "enable": { - "type": "boolean" - }, - "region_code": { - "type": "string" - }, - "region_id": { - "type": "integer" - }, - "region_name": { - "type": "string" - }, - "relay_url": { - "$ref": "#/definitions/serpent.URL" - }, - "stun_addresses": { - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "codersdk.DangerousConfig": { - "type": "object", - "properties": { - "allow_all_cors": { - "type": "boolean" - }, - "allow_path_app_sharing": { - "type": "boolean" - }, - "allow_path_app_site_owner_access": { - "type": "boolean" - } - } - }, - "codersdk.DeleteWorkspaceAgentPortShareRequest": { - "type": "object", - "properties": { - "agent_name": { - "type": "string" - }, - "port": { - "type": "integer" - } - } - }, - "codersdk.DeploymentConfig": { - "type": "object", - "properties": { - "config": { - "$ref": "#/definitions/codersdk.DeploymentValues" - }, - "options": { - "type": "array", - "items": { - "$ref": "#/definitions/serpent.Option" - } - } - } - }, - "codersdk.DeploymentStats": { - "type": "object", - "properties": { - "aggregated_from": { - "description": "AggregatedFrom is the time in which stats are aggregated from.\nThis might be back in time a specific duration or interval.", - "type": "string", - "format": "date-time" - }, - "collected_at": { - "description": "CollectedAt is the time in which stats are collected at.", - "type": "string", - "format": "date-time" - }, - "next_update_at": { - "description": "NextUpdateAt is the time when the next batch of stats will\nbe updated.", - "type": "string", - "format": "date-time" - }, - "session_count": { - "$ref": "#/definitions/codersdk.SessionCountDeploymentStats" - }, - "workspaces": { - "$ref": "#/definitions/codersdk.WorkspaceDeploymentStats" - } - } - }, - "codersdk.DeploymentValues": { - "type": "object", - "properties": { - "access_url": { - "$ref": "#/definitions/serpent.URL" - }, - "address": { - "description": "DEPRECATED: Use HTTPAddress or TLS.Address instead.", - "allOf": [ - { - "$ref": "#/definitions/serpent.HostPort" - } - ] - }, - "agent_fallback_troubleshooting_url": { - "$ref": "#/definitions/serpent.URL" - }, - "agent_stat_refresh_interval": { - "type": "integer" - }, - "allow_workspace_renames": { - "type": "boolean" - }, - "autobuild_poll_interval": { - "type": "integer" - }, - "browser_only": { - "type": "boolean" - }, - "cache_directory": { - "type": "string" - }, - "cli_upgrade_message": { - "type": "string" - }, - "config": { - "type": "string" - }, - "config_ssh": { - "$ref": "#/definitions/codersdk.SSHConfig" - }, - "dangerous": { - "$ref": "#/definitions/codersdk.DangerousConfig" - }, - "derp": { - "$ref": "#/definitions/codersdk.DERP" - }, - "disable_owner_workspace_exec": { - "type": "boolean" - }, - "disable_password_auth": { - "type": "boolean" - }, - "disable_path_apps": { - "type": "boolean" - }, - "docs_url": { - "$ref": "#/definitions/serpent.URL" - }, - "enable_terraform_debug_mode": { - "type": "boolean" - }, - "experiments": { - "type": "array", - "items": { - "type": "string" - } - }, - "external_auth": { - "$ref": "#/definitions/serpent.Struct-array_codersdk_ExternalAuthConfig" - }, - "external_token_encryption_keys": { - "type": "array", - "items": { - "type": "string" - } - }, - "healthcheck": { - "$ref": "#/definitions/codersdk.HealthcheckConfig" - }, - "http_address": { - "description": "HTTPAddress is a string because it may be set to zero to disable.", - "type": "string" - }, - "in_memory_database": { - "type": "boolean" - }, - "job_hang_detector_interval": { - "type": "integer" - }, - "logging": { - "$ref": "#/definitions/codersdk.LoggingConfig" - }, - "metrics_cache_refresh_interval": { - "type": "integer" - }, - "notifications": { - "$ref": "#/definitions/codersdk.NotificationsConfig" - }, - "oauth2": { - "$ref": "#/definitions/codersdk.OAuth2Config" - }, - "oidc": { - "$ref": "#/definitions/codersdk.OIDCConfig" - }, - "pg_auth": { - "type": "string" - }, - "pg_connection_url": { - "type": "string" - }, - "pprof": { - "$ref": "#/definitions/codersdk.PprofConfig" - }, - "prometheus": { - "$ref": "#/definitions/codersdk.PrometheusConfig" - }, - "provisioner": { - "$ref": "#/definitions/codersdk.ProvisionerConfig" - }, - "proxy_health_status_interval": { - "type": "integer" - }, - "proxy_trusted_headers": { - "type": "array", - "items": { - "type": "string" - } - }, - "proxy_trusted_origins": { - "type": "array", - "items": { - "type": "string" - } - }, - "rate_limit": { - "$ref": "#/definitions/codersdk.RateLimitConfig" - }, - "redirect_to_access_url": { - "type": "boolean" - }, - "scim_api_key": { - "type": "string" - }, - "secure_auth_cookie": { - "type": "boolean" - }, - "session_lifetime": { - "$ref": "#/definitions/codersdk.SessionLifetime" - }, - "ssh_keygen_algorithm": { - "type": "string" - }, - "strict_transport_security": { - "type": "integer" - }, - "strict_transport_security_options": { - "type": "array", - "items": { - "type": "string" - } - }, - "support": { - "$ref": "#/definitions/codersdk.SupportConfig" - }, - "swagger": { - "$ref": "#/definitions/codersdk.SwaggerConfig" - }, - "telemetry": { - "$ref": "#/definitions/codersdk.TelemetryConfig" - }, - "terms_of_service_url": { - "type": "string" - }, - "tls": { - "$ref": "#/definitions/codersdk.TLSConfig" - }, - "trace": { - "$ref": "#/definitions/codersdk.TraceConfig" - }, - "update_check": { - "type": "boolean" - }, - "user_quiet_hours_schedule": { - "$ref": "#/definitions/codersdk.UserQuietHoursScheduleConfig" - }, - "verbose": { - "type": "boolean" - }, - "web_terminal_renderer": { - "type": "string" - }, - "wgtunnel_host": { - "type": "string" - }, - "wildcard_access_url": { - "type": "string" - }, - "write_config": { - "type": "boolean" - } - } - }, - "codersdk.DisplayApp": { - "type": "string", - "enum": [ - "vscode", - "vscode_insiders", - "web_terminal", - "port_forwarding_helper", - "ssh_helper" - ], - "x-enum-varnames": [ - "DisplayAppVSCodeDesktop", - "DisplayAppVSCodeInsiders", - "DisplayAppWebTerminal", - "DisplayAppPortForward", - "DisplayAppSSH" - ] - }, - "codersdk.Entitlement": { - "type": "string", - "enum": ["entitled", "grace_period", "not_entitled"], - "x-enum-varnames": [ - "EntitlementEntitled", - "EntitlementGracePeriod", - "EntitlementNotEntitled" - ] - }, - "codersdk.Entitlements": { - "type": "object", - "properties": { - "errors": { - "type": "array", - "items": { - "type": "string" - } - }, - "features": { - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/codersdk.Feature" - } - }, - "has_license": { - "type": "boolean" - }, - "refreshed_at": { - "type": "string", - "format": "date-time" - }, - "require_telemetry": { - "type": "boolean" - }, - "trial": { - "type": "boolean" - }, - "warnings": { - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "codersdk.Experiment": { - "type": "string", - "enum": [ - "example", - "auto-fill-parameters", - "multi-organization", - "custom-roles", - "notifications", - "workspace-usage" - ], - "x-enum-comments": { - "ExperimentAutoFillParameters": "This should not be taken out of experiments until we have redesigned the feature.", - "ExperimentCustomRoles": "Allows creating runtime custom roles.", - "ExperimentExample": "This isn't used for anything.", - "ExperimentMultiOrganization": "Requires organization context for interactions, default org is assumed.", - "ExperimentNotifications": "Sends notifications via SMTP and webhooks following certain events.", - "ExperimentWorkspaceUsage": "Enables the new workspace usage tracking." - }, - "x-enum-varnames": [ - "ExperimentExample", - "ExperimentAutoFillParameters", - "ExperimentMultiOrganization", - "ExperimentCustomRoles", - "ExperimentNotifications", - "ExperimentWorkspaceUsage" - ] - }, - "codersdk.ExternalAuth": { - "type": "object", - "properties": { - "app_install_url": { - "description": "AppInstallURL is the URL to install the app.", - "type": "string" - }, - "app_installable": { - "description": "AppInstallable is true if the request for app installs was successful.", - "type": "boolean" - }, - "authenticated": { - "type": "boolean" - }, - "device": { - "type": "boolean" - }, - "display_name": { - "type": "string" - }, - "installations": { - "description": "AppInstallations are the installations that the user has access to.", - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.ExternalAuthAppInstallation" - } - }, - "user": { - "description": "User is the user that authenticated with the provider.", - "allOf": [ - { - "$ref": "#/definitions/codersdk.ExternalAuthUser" - } - ] - } - } - }, - "codersdk.ExternalAuthAppInstallation": { - "type": "object", - "properties": { - "account": { - "$ref": "#/definitions/codersdk.ExternalAuthUser" - }, - "configure_url": { - "type": "string" - }, - "id": { - "type": "integer" - } - } - }, - "codersdk.ExternalAuthConfig": { - "type": "object", - "properties": { - "app_install_url": { - "type": "string" - }, - "app_installations_url": { - "type": "string" - }, - "auth_url": { - "type": "string" - }, - "client_id": { - "type": "string" - }, - "device_code_url": { - "type": "string" - }, - "device_flow": { - "type": "boolean" - }, - "display_icon": { - "description": "DisplayIcon is a URL to an icon to display in the UI.", - "type": "string" - }, - "display_name": { - "description": "DisplayName is shown in the UI to identify the auth config.", - "type": "string" - }, - "id": { - "description": "ID is a unique identifier for the auth config.\nIt defaults to `type` when not provided.", - "type": "string" - }, - "no_refresh": { - "type": "boolean" - }, - "regex": { - "description": "Regex allows API requesters to match an auth config by\na string (e.g. coder.com) instead of by it's type.\n\nGit clone makes use of this by parsing the URL from:\n'Username for \"https://github.com\":'\nAnd sending it to the Coder server to match against the Regex.", - "type": "string" - }, - "scopes": { - "type": "array", - "items": { - "type": "string" - } - }, - "token_url": { - "type": "string" - }, - "type": { - "description": "Type is the type of external auth config.", - "type": "string" - }, - "validate_url": { - "type": "string" - } - } - }, - "codersdk.ExternalAuthDevice": { - "type": "object", - "properties": { - "device_code": { - "type": "string" - }, - "expires_in": { - "type": "integer" - }, - "interval": { - "type": "integer" - }, - "user_code": { - "type": "string" - }, - "verification_uri": { - "type": "string" - } - } - }, - "codersdk.ExternalAuthLink": { - "type": "object", - "properties": { - "authenticated": { - "type": "boolean" - }, - "created_at": { - "type": "string", - "format": "date-time" - }, - "expires": { - "type": "string", - "format": "date-time" - }, - "has_refresh_token": { - "type": "boolean" - }, - "provider_id": { - "type": "string" - }, - "updated_at": { - "type": "string", - "format": "date-time" - }, - "validate_error": { - "type": "string" - } - } - }, - "codersdk.ExternalAuthUser": { - "type": "object", - "properties": { - "avatar_url": { - "type": "string" - }, - "id": { - "type": "integer" - }, - "login": { - "type": "string" - }, - "name": { - "type": "string" - }, - "profile_url": { - "type": "string" - } - } - }, - "codersdk.Feature": { - "type": "object", - "properties": { - "actual": { - "type": "integer" - }, - "enabled": { - "type": "boolean" - }, - "entitlement": { - "$ref": "#/definitions/codersdk.Entitlement" - }, - "limit": { - "type": "integer" - } - } - }, - "codersdk.GenerateAPIKeyResponse": { - "type": "object", - "properties": { - "key": { - "type": "string" - } - } - }, - "codersdk.GetUsersResponse": { - "type": "object", - "properties": { - "count": { - "type": "integer" - }, - "users": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.User" - } - } - } - }, - "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.Group": { - "type": "object", - "properties": { - "avatar_url": { - "type": "string" - }, - "display_name": { - "type": "string" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "members": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.ReducedUser" - } - }, - "name": { - "type": "string" - }, - "organization_id": { - "type": "string", - "format": "uuid" - }, - "quota_allowance": { - "type": "integer" - }, - "source": { - "$ref": "#/definitions/codersdk.GroupSource" - }, - "total_member_count": { - "description": "How many members are in this group. Shows the total count,\neven if the user is not authorized to read group member details.\nMay be greater than `len(Group.Members)`.", - "type": "integer" - } - } - }, - "codersdk.GroupSource": { - "type": "string", - "enum": ["user", "oidc"], - "x-enum-varnames": ["GroupSourceUser", "GroupSourceOIDC"] - }, - "codersdk.Healthcheck": { - "type": "object", - "properties": { - "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.HealthcheckConfig": { - "type": "object", - "properties": { - "refresh": { - "type": "integer" - }, - "threshold_database": { - "type": "integer" - } - } - }, - "codersdk.InsightsReportInterval": { - "type": "string", - "enum": ["day", "week"], - "x-enum-varnames": [ - "InsightsReportIntervalDay", - "InsightsReportIntervalWeek" - ] - }, - "codersdk.IssueReconnectingPTYSignedTokenRequest": { - "type": "object", - "required": ["agentID", "url"], - "properties": { - "agentID": { - "type": "string", - "format": "uuid" - }, - "url": { - "description": "URL is the URL of the reconnecting-pty endpoint you are connecting to.", - "type": "string" - } - } - }, - "codersdk.IssueReconnectingPTYSignedTokenResponse": { - "type": "object", - "properties": { - "signed_token": { - "type": "string" - } - } - }, - "codersdk.JFrogXrayScan": { - "type": "object", - "properties": { - "agent_id": { - "type": "string", - "format": "uuid" - }, - "critical": { - "type": "integer" - }, - "high": { - "type": "integer" - }, - "medium": { - "type": "integer" - }, - "results_url": { - "type": "string" - }, - "workspace_id": { - "type": "string", - "format": "uuid" - } - } - }, - "codersdk.JobErrorCode": { - "type": "string", - "enum": ["REQUIRED_TEMPLATE_VARIABLES"], - "x-enum-varnames": ["RequiredTemplateVariables"] - }, - "codersdk.License": { - "type": "object", - "properties": { - "claims": { - "description": "Claims are the JWT claims asserted by the license. Here we use\na generic string map to ensure that all data from the server is\nparsed verbatim, not just the fields this version of Coder\nunderstands.", - "type": "object", - "additionalProperties": true - }, - "id": { - "type": "integer" - }, - "uploaded_at": { - "type": "string", - "format": "date-time" - }, - "uuid": { - "type": "string", - "format": "uuid" - } - } - }, - "codersdk.LinkConfig": { - "type": "object", - "properties": { - "icon": { - "type": "string", - "enum": ["bug", "chat", "docs"] - }, - "name": { - "type": "string" - }, - "target": { - "type": "string" - } - } - }, - "codersdk.LogLevel": { - "type": "string", - "enum": ["trace", "debug", "info", "warn", "error"], - "x-enum-varnames": [ - "LogLevelTrace", - "LogLevelDebug", - "LogLevelInfo", - "LogLevelWarn", - "LogLevelError" - ] - }, - "codersdk.LogSource": { - "type": "string", - "enum": ["provisioner_daemon", "provisioner"], - "x-enum-varnames": ["LogSourceProvisionerDaemon", "LogSourceProvisioner"] - }, - "codersdk.LoggingConfig": { - "type": "object", - "properties": { - "human": { - "type": "string" - }, - "json": { - "type": "string" - }, - "log_filter": { - "type": "array", - "items": { - "type": "string" - } - }, - "stackdriver": { - "type": "string" - } - } - }, - "codersdk.LoginType": { - "type": "string", - "enum": ["", "password", "github", "oidc", "token", "none"], - "x-enum-varnames": [ - "LoginTypeUnknown", - "LoginTypePassword", - "LoginTypeGithub", - "LoginTypeOIDC", - "LoginTypeToken", - "LoginTypeNone" - ] - }, - "codersdk.LoginWithPasswordRequest": { - "type": "object", - "required": ["email", "password"], - "properties": { - "email": { - "type": "string", - "format": "email" - }, - "password": { - "type": "string" - } - } - }, - "codersdk.LoginWithPasswordResponse": { - "type": "object", - "required": ["session_token"], - "properties": { - "session_token": { - "type": "string" - } - } - }, - "codersdk.MinimalOrganization": { - "type": "object", - "required": ["id"], - "properties": { - "display_name": { - "type": "string" - }, - "icon": { - "type": "string" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "name": { - "type": "string" - } - } - }, - "codersdk.MinimalUser": { - "type": "object", - "required": ["id", "username"], - "properties": { - "avatar_url": { - "type": "string", - "format": "uri" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "username": { - "type": "string" - } - } - }, - "codersdk.NotificationMethodsResponse": { - "type": "object", - "properties": { - "available": { - "type": "array", - "items": { - "type": "string" - } - }, - "default": { - "type": "string" - } - } - }, - "codersdk.NotificationPreference": { - "type": "object", - "properties": { - "disabled": { - "type": "boolean" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "updated_at": { - "type": "string", - "format": "date-time" - } - } - }, - "codersdk.NotificationTemplate": { - "type": "object", - "properties": { - "actions": { - "type": "string" - }, - "body_template": { - "type": "string" - }, - "group": { - "type": "string" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "kind": { - "type": "string" - }, - "method": { - "type": "string" - }, - "name": { - "type": "string" - }, - "title_template": { - "type": "string" - } - } - }, - "codersdk.NotificationsConfig": { - "type": "object", - "properties": { - "dispatch_timeout": { - "description": "How long to wait while a notification is being sent before giving up.", - "type": "integer" - }, - "email": { - "description": "SMTP settings.", - "allOf": [ - { - "$ref": "#/definitions/codersdk.NotificationsEmailConfig" - } - ] - }, - "fetch_interval": { - "description": "How often to query the database for queued notifications.", - "type": "integer" - }, - "lease_count": { - "description": "How many notifications a notifier should lease per fetch interval.", - "type": "integer" - }, - "lease_period": { - "description": "How long a notifier should lease a message. This is effectively how long a notification is 'owned'\nby a notifier, and once this period expires it will be available for lease by another notifier. Leasing\nis important in order for multiple running notifiers to not pick the same messages to deliver concurrently.\nThis lease period will only expire if a notifier shuts down ungracefully; a dispatch of the notification\nreleases the lease.", - "type": "integer" - }, - "max_send_attempts": { - "description": "The upper limit of attempts to send a notification.", - "type": "integer" - }, - "method": { - "description": "Which delivery method to use (available options: 'smtp', 'webhook').", - "type": "string" - }, - "retry_interval": { - "description": "The minimum time between retries.", - "type": "integer" - }, - "sync_buffer_size": { - "description": "The notifications system buffers message updates in memory to ease pressure on the database.\nThis option controls how many updates are kept in memory. The lower this value the\nlower the change of state inconsistency in a non-graceful shutdown - but it also increases load on the\ndatabase. It is recommended to keep this option at its default value.", - "type": "integer" - }, - "sync_interval": { - "description": "The notifications system buffers message updates in memory to ease pressure on the database.\nThis option controls how often it synchronizes its state with the database. The shorter this value the\nlower the change of state inconsistency in a non-graceful shutdown - but it also increases load on the\ndatabase. It is recommended to keep this option at its default value.", - "type": "integer" - }, - "webhook": { - "description": "Webhook settings.", - "allOf": [ - { - "$ref": "#/definitions/codersdk.NotificationsWebhookConfig" - } - ] - } - } - }, - "codersdk.NotificationsEmailAuthConfig": { - "type": "object", - "properties": { - "identity": { - "description": "Identity for PLAIN auth.", - "type": "string" - }, - "password": { - "description": "Password for LOGIN/PLAIN auth.", - "type": "string" - }, - "password_file": { - "description": "File from which to load the password for LOGIN/PLAIN auth.", - "type": "string" - }, - "username": { - "description": "Username for LOGIN/PLAIN auth.", - "type": "string" - } - } - }, - "codersdk.NotificationsEmailConfig": { - "type": "object", - "properties": { - "auth": { - "description": "Authentication details.", - "allOf": [ - { - "$ref": "#/definitions/codersdk.NotificationsEmailAuthConfig" - } - ] - }, - "force_tls": { - "description": "ForceTLS causes a TLS connection to be attempted.", - "type": "boolean" - }, - "from": { - "description": "The sender's address.", - "type": "string" - }, - "hello": { - "description": "The hostname identifying the SMTP server.", - "type": "string" - }, - "smarthost": { - "description": "The intermediary SMTP host through which emails are sent (host:port).", - "allOf": [ - { - "$ref": "#/definitions/serpent.HostPort" - } - ] - }, - "tls": { - "description": "TLS details.", - "allOf": [ - { - "$ref": "#/definitions/codersdk.NotificationsEmailTLSConfig" - } - ] - } - } - }, - "codersdk.NotificationsEmailTLSConfig": { - "type": "object", - "properties": { - "ca_file": { - "description": "CAFile specifies the location of the CA certificate to use.", - "type": "string" - }, - "cert_file": { - "description": "CertFile specifies the location of the certificate to use.", - "type": "string" - }, - "insecure_skip_verify": { - "description": "InsecureSkipVerify skips target certificate validation.", - "type": "boolean" - }, - "key_file": { - "description": "KeyFile specifies the location of the key to use.", - "type": "string" - }, - "server_name": { - "description": "ServerName to verify the hostname for the targets.", - "type": "string" - }, - "start_tls": { - "description": "StartTLS attempts to upgrade plain connections to TLS.", - "type": "boolean" - } - } - }, - "codersdk.NotificationsSettings": { - "type": "object", - "properties": { - "notifier_paused": { - "type": "boolean" - } - } - }, - "codersdk.NotificationsWebhookConfig": { - "type": "object", - "properties": { - "endpoint": { - "description": "The URL to which the payload will be sent with an HTTP POST request.", - "allOf": [ - { - "$ref": "#/definitions/serpent.URL" - } - ] - } - } - }, - "codersdk.OAuth2AppEndpoints": { - "type": "object", - "properties": { - "authorization": { - "type": "string" - }, - "device_authorization": { - "description": "DeviceAuth is optional.", - "type": "string" - }, - "token": { - "type": "string" - } - } - }, - "codersdk.OAuth2Config": { - "type": "object", - "properties": { - "github": { - "$ref": "#/definitions/codersdk.OAuth2GithubConfig" - } - } - }, - "codersdk.OAuth2GithubConfig": { - "type": "object", - "properties": { - "allow_everyone": { - "type": "boolean" - }, - "allow_signups": { - "type": "boolean" - }, - "allowed_orgs": { - "type": "array", - "items": { - "type": "string" - } - }, - "allowed_teams": { - "type": "array", - "items": { - "type": "string" - } - }, - "client_id": { - "type": "string" - }, - "client_secret": { - "type": "string" - }, - "enterprise_base_url": { - "type": "string" - } - } - }, - "codersdk.OAuth2ProviderApp": { - "type": "object", - "properties": { - "callback_url": { - "type": "string" - }, - "endpoints": { - "description": "Endpoints are included in the app response for easier discovery. The OAuth2\nspec does not have a defined place to find these (for comparison, OIDC has\na '/.well-known/openid-configuration' endpoint).", - "allOf": [ - { - "$ref": "#/definitions/codersdk.OAuth2AppEndpoints" - } - ] - }, - "icon": { - "type": "string" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "name": { - "type": "string" - } - } - }, - "codersdk.OAuth2ProviderAppSecret": { - "type": "object", - "properties": { - "client_secret_truncated": { - "type": "string" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "last_used_at": { - "type": "string" - } - } - }, - "codersdk.OAuth2ProviderAppSecretFull": { - "type": "object", - "properties": { - "client_secret_full": { - "type": "string" - }, - "id": { - "type": "string", - "format": "uuid" - } - } - }, - "codersdk.OAuthConversionResponse": { - "type": "object", - "properties": { - "expires_at": { - "type": "string", - "format": "date-time" - }, - "state_string": { - "type": "string" - }, - "to_type": { - "$ref": "#/definitions/codersdk.LoginType" - }, - "user_id": { - "type": "string", - "format": "uuid" - } - } - }, - "codersdk.OIDCAuthMethod": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "iconUrl": { - "type": "string" - }, - "signInText": { - "type": "string" - } - } - }, - "codersdk.OIDCConfig": { - "type": "object", - "properties": { - "allow_signups": { - "type": "boolean" - }, - "auth_url_params": { - "type": "object" - }, - "client_cert_file": { - "type": "string" - }, - "client_id": { - "type": "string" - }, - "client_key_file": { - "description": "ClientKeyFile \u0026 ClientCertFile are used in place of ClientSecret for PKI auth.", - "type": "string" - }, - "client_secret": { - "type": "string" - }, - "email_domain": { - "type": "array", - "items": { - "type": "string" - } - }, - "email_field": { - "type": "string" - }, - "group_allow_list": { - "type": "array", - "items": { - "type": "string" - } - }, - "group_auto_create": { - "type": "boolean" - }, - "group_mapping": { - "type": "object" - }, - "group_regex_filter": { - "$ref": "#/definitions/serpent.Regexp" - }, - "groups_field": { - "type": "string" - }, - "icon_url": { - "$ref": "#/definitions/serpent.URL" - }, - "ignore_email_verified": { - "type": "boolean" - }, - "ignore_user_info": { - "type": "boolean" - }, - "issuer_url": { - "type": "string" - }, - "name_field": { - "type": "string" - }, - "scopes": { - "type": "array", - "items": { - "type": "string" - } - }, - "sign_in_text": { - "type": "string" - }, - "signups_disabled_text": { - "type": "string" - }, - "skip_issuer_checks": { - "type": "boolean" - }, - "user_role_field": { - "type": "string" - }, - "user_role_mapping": { - "type": "object" - }, - "user_roles_default": { - "type": "array", - "items": { - "type": "string" - } - }, - "username_field": { - "type": "string" - } - } - }, - "codersdk.Organization": { - "type": "object", - "required": ["created_at", "id", "is_default", "updated_at"], - "properties": { - "created_at": { - "type": "string", - "format": "date-time" - }, - "description": { - "type": "string" - }, - "display_name": { - "type": "string" - }, - "icon": { - "type": "string" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "is_default": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "updated_at": { - "type": "string", - "format": "date-time" - } - } - }, - "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.SlimRole" - } - }, - "updated_at": { - "type": "string", - "format": "date-time" - }, - "user_id": { - "type": "string", - "format": "uuid" - } - } - }, - "codersdk.OrganizationMemberWithUserData": { - "type": "object", - "properties": { - "avatar_url": { - "type": "string" - }, - "created_at": { - "type": "string", - "format": "date-time" - }, - "email": { - "type": "string" - }, - "global_roles": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.SlimRole" - } - }, - "name": { - "type": "string" - }, - "organization_id": { - "type": "string", - "format": "uuid" - }, - "roles": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.SlimRole" - } - }, - "updated_at": { - "type": "string", - "format": "date-time" - }, - "user_id": { - "type": "string", - "format": "uuid" - }, - "username": { - "type": "string" - } - } - }, - "codersdk.PatchGroupRequest": { - "type": "object", - "properties": { - "add_users": { - "type": "array", - "items": { - "type": "string" - } - }, - "avatar_url": { - "type": "string" - }, - "display_name": { - "type": "string" - }, - "name": { - "type": "string" - }, - "quota_allowance": { - "type": "integer" - }, - "remove_users": { - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "codersdk.PatchTemplateVersionRequest": { - "type": "object", - "properties": { - "message": { - "type": "string" - }, - "name": { - "type": "string" - } - } - }, - "codersdk.PatchWorkspaceProxy": { - "type": "object", - "required": ["display_name", "icon", "id", "name"], - "properties": { - "display_name": { - "type": "string" - }, - "icon": { - "type": "string" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "name": { - "type": "string" - }, - "regenerate_token": { - "type": "boolean" - } - } - }, - "codersdk.Permission": { - "type": "object", - "properties": { - "action": { - "$ref": "#/definitions/codersdk.RBACAction" - }, - "negate": { - "description": "Negate makes this a negative permission", - "type": "boolean" - }, - "resource_type": { - "$ref": "#/definitions/codersdk.RBACResource" - } - } - }, - "codersdk.PostOAuth2ProviderAppRequest": { - "type": "object", - "required": ["callback_url", "name"], - "properties": { - "callback_url": { - "type": "string" - }, - "icon": { - "type": "string" - }, - "name": { - "type": "string" - } - } - }, - "codersdk.PostWorkspaceUsageRequest": { - "type": "object", - "properties": { - "agent_id": { - "type": "string", - "format": "uuid" - }, - "app_name": { - "$ref": "#/definitions/codersdk.UsageAppName" - } - } - }, - "codersdk.PprofConfig": { - "type": "object", - "properties": { - "address": { - "$ref": "#/definitions/serpent.HostPort" - }, - "enable": { - "type": "boolean" - } - } - }, - "codersdk.PrometheusConfig": { - "type": "object", - "properties": { - "address": { - "$ref": "#/definitions/serpent.HostPort" - }, - "aggregate_agent_stats_by": { - "type": "array", - "items": { - "type": "string" - } - }, - "collect_agent_stats": { - "type": "boolean" - }, - "collect_db_metrics": { - "type": "boolean" - }, - "enable": { - "type": "boolean" - } - } - }, - "codersdk.ProvisionerConfig": { - "type": "object", - "properties": { - "daemon_poll_interval": { - "type": "integer" - }, - "daemon_poll_jitter": { - "type": "integer" - }, - "daemon_psk": { - "type": "string" - }, - "daemon_types": { - "type": "array", - "items": { - "type": "string" - } - }, - "daemons": { - "description": "Daemons is the number of built-in terraform provisioners.", - "type": "integer" - }, - "force_cancel_interval": { - "type": "integer" - } - } - }, - "codersdk.ProvisionerDaemon": { - "type": "object", - "properties": { - "api_version": { - "type": "string" - }, - "created_at": { - "type": "string", - "format": "date-time" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "last_seen_at": { - "type": "string", - "format": "date-time" - }, - "name": { - "type": "string" - }, - "organization_id": { - "type": "string", - "format": "uuid" - }, - "provisioners": { - "type": "array", - "items": { - "type": "string" - } - }, - "tags": { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "version": { - "type": "string" - } - } - }, - "codersdk.ProvisionerJob": { - "type": "object", - "properties": { - "canceled_at": { - "type": "string", - "format": "date-time" - }, - "completed_at": { - "type": "string", - "format": "date-time" - }, - "created_at": { - "type": "string", - "format": "date-time" - }, - "error": { - "type": "string" - }, - "error_code": { - "enum": ["REQUIRED_TEMPLATE_VARIABLES"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.JobErrorCode" - } - ] - }, - "file_id": { - "type": "string", - "format": "uuid" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "queue_position": { - "type": "integer" - }, - "queue_size": { - "type": "integer" - }, - "started_at": { - "type": "string", - "format": "date-time" - }, - "status": { - "enum": [ - "pending", - "running", - "succeeded", - "canceling", - "canceled", - "failed" - ], - "allOf": [ - { - "$ref": "#/definitions/codersdk.ProvisionerJobStatus" - } - ] - }, - "tags": { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "worker_id": { - "type": "string", - "format": "uuid" - } - } - }, - "codersdk.ProvisionerJobLog": { - "type": "object", - "properties": { - "created_at": { - "type": "string", - "format": "date-time" - }, - "id": { - "type": "integer" - }, - "log_level": { - "enum": ["trace", "debug", "info", "warn", "error"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.LogLevel" - } - ] - }, - "log_source": { - "$ref": "#/definitions/codersdk.LogSource" - }, - "output": { - "type": "string" - }, - "stage": { - "type": "string" - } - } - }, - "codersdk.ProvisionerJobStatus": { - "type": "string", - "enum": [ - "pending", - "running", - "succeeded", - "canceling", - "canceled", - "failed", - "unknown" - ], - "x-enum-varnames": [ - "ProvisionerJobPending", - "ProvisionerJobRunning", - "ProvisionerJobSucceeded", - "ProvisionerJobCanceling", - "ProvisionerJobCanceled", - "ProvisionerJobFailed", - "ProvisionerJobUnknown" - ] - }, - "codersdk.ProvisionerKey": { - "type": "object", - "properties": { - "created_at": { - "type": "string", - "format": "date-time" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "name": { - "type": "string" - }, - "organization": { - "type": "string", - "format": "uuid" - }, - "tags": { - "type": "object", - "additionalProperties": { - "type": "string" - } - } - } - }, - "codersdk.ProvisionerLogLevel": { - "type": "string", - "enum": ["debug"], - "x-enum-varnames": ["ProvisionerLogLevelDebug"] - }, - "codersdk.ProvisionerStorageMethod": { - "type": "string", - "enum": ["file"], - "x-enum-varnames": ["ProvisionerStorageMethodFile"] - }, - "codersdk.ProxyHealthReport": { - "type": "object", - "properties": { - "errors": { - "description": "Errors are problems that prevent the workspace proxy from being healthy", - "type": "array", - "items": { - "type": "string" - } - }, - "warnings": { - "description": "Warnings do not prevent the workspace proxy from being healthy, but\nshould be addressed.", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "codersdk.ProxyHealthStatus": { - "type": "string", - "enum": ["ok", "unreachable", "unhealthy", "unregistered"], - "x-enum-varnames": [ - "ProxyHealthy", - "ProxyUnreachable", - "ProxyUnhealthy", - "ProxyUnregistered" - ] - }, - "codersdk.PutExtendWorkspaceRequest": { - "type": "object", - "required": ["deadline"], - "properties": { - "deadline": { - "type": "string", - "format": "date-time" - } - } - }, - "codersdk.PutOAuth2ProviderAppRequest": { - "type": "object", - "required": ["callback_url", "name"], - "properties": { - "callback_url": { - "type": "string" - }, - "icon": { - "type": "string" - }, - "name": { - "type": "string" - } - } - }, - "codersdk.RBACAction": { - "type": "string", - "enum": [ - "application_connect", - "assign", - "create", - "delete", - "read", - "read_personal", - "ssh", - "update", - "update_personal", - "use", - "view_insights", - "start", - "stop" - ], - "x-enum-varnames": [ - "ActionApplicationConnect", - "ActionAssign", - "ActionCreate", - "ActionDelete", - "ActionRead", - "ActionReadPersonal", - "ActionSSH", - "ActionUpdate", - "ActionUpdatePersonal", - "ActionUse", - "ActionViewInsights", - "ActionWorkspaceStart", - "ActionWorkspaceStop" - ] - }, - "codersdk.RBACResource": { - "type": "string", - "enum": [ - "*", - "api_key", - "assign_org_role", - "assign_role", - "audit_log", - "debug_info", - "deployment_config", - "deployment_stats", - "file", - "group", - "group_member", - "license", - "notification_preference", - "notification_template", - "oauth2_app", - "oauth2_app_code_token", - "oauth2_app_secret", - "organization", - "organization_member", - "provisioner_daemon", - "provisioner_keys", - "replicas", - "system", - "tailnet_coordinator", - "template", - "user", - "workspace", - "workspace_dormant", - "workspace_proxy" - ], - "x-enum-varnames": [ - "ResourceWildcard", - "ResourceApiKey", - "ResourceAssignOrgRole", - "ResourceAssignRole", - "ResourceAuditLog", - "ResourceDebugInfo", - "ResourceDeploymentConfig", - "ResourceDeploymentStats", - "ResourceFile", - "ResourceGroup", - "ResourceGroupMember", - "ResourceLicense", - "ResourceNotificationPreference", - "ResourceNotificationTemplate", - "ResourceOauth2App", - "ResourceOauth2AppCodeToken", - "ResourceOauth2AppSecret", - "ResourceOrganization", - "ResourceOrganizationMember", - "ResourceProvisionerDaemon", - "ResourceProvisionerKeys", - "ResourceReplicas", - "ResourceSystem", - "ResourceTailnetCoordinator", - "ResourceTemplate", - "ResourceUser", - "ResourceWorkspace", - "ResourceWorkspaceDormant", - "ResourceWorkspaceProxy" - ] - }, - "codersdk.RateLimitConfig": { - "type": "object", - "properties": { - "api": { - "type": "integer" - }, - "disable_all": { - "type": "boolean" - } - } - }, - "codersdk.ReducedUser": { - "type": "object", - "required": ["created_at", "email", "id", "username"], - "properties": { - "avatar_url": { - "type": "string", - "format": "uri" - }, - "created_at": { - "type": "string", - "format": "date-time" - }, - "email": { - "type": "string", - "format": "email" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "last_seen_at": { - "type": "string", - "format": "date-time" - }, - "login_type": { - "$ref": "#/definitions/codersdk.LoginType" - }, - "name": { - "type": "string" - }, - "status": { - "enum": ["active", "suspended"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.UserStatus" - } - ] - }, - "theme_preference": { - "type": "string" - }, - "updated_at": { - "type": "string", - "format": "date-time" - }, - "username": { - "type": "string" - } - } - }, - "codersdk.Region": { - "type": "object", - "properties": { - "display_name": { - "type": "string" - }, - "healthy": { - "type": "boolean" - }, - "icon_url": { - "type": "string" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "name": { - "type": "string" - }, - "path_app_url": { - "description": "PathAppURL is the URL to the base path for path apps. Optional\nunless wildcard_hostname is set.\nE.g. https://us.example.com", - "type": "string" - }, - "wildcard_hostname": { - "description": "WildcardHostname is the wildcard hostname for subdomain apps.\nE.g. *.us.example.com\nE.g. *--suffix.au.example.com\nOptional. Does not need to be on the same domain as PathAppURL.", - "type": "string" - } - } - }, - "codersdk.RegionsResponse-codersdk_Region": { - "type": "object", - "properties": { - "regions": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Region" - } - } - } - }, - "codersdk.RegionsResponse-codersdk_WorkspaceProxy": { - "type": "object", - "properties": { - "regions": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceProxy" - } - } - } - }, - "codersdk.Replica": { - "type": "object", - "properties": { - "created_at": { - "description": "CreatedAt is the timestamp when the replica was first seen.", - "type": "string", - "format": "date-time" - }, - "database_latency": { - "description": "DatabaseLatency is the latency in microseconds to the database.", - "type": "integer" - }, - "error": { - "description": "Error is the replica error.", - "type": "string" - }, - "hostname": { - "description": "Hostname is the hostname of the replica.", - "type": "string" - }, - "id": { - "description": "ID is the unique identifier for the replica.", - "type": "string", - "format": "uuid" - }, - "region_id": { - "description": "RegionID is the region of the replica.", - "type": "integer" - }, - "relay_address": { - "description": "RelayAddress is the accessible address to relay DERP connections.", - "type": "string" - } - } - }, - "codersdk.ResolveAutostartResponse": { - "type": "object", - "properties": { - "parameter_mismatch": { - "type": "boolean" - } - } - }, - "codersdk.ResourceType": { - "type": "string", - "enum": [ - "template", - "template_version", - "user", - "workspace", - "workspace_build", - "git_ssh_key", - "api_key", - "group", - "license", - "convert_login", - "health_settings", - "notifications_settings", - "workspace_proxy", - "organization", - "oauth2_provider_app", - "oauth2_provider_app_secret", - "custom_role" - ], - "x-enum-varnames": [ - "ResourceTypeTemplate", - "ResourceTypeTemplateVersion", - "ResourceTypeUser", - "ResourceTypeWorkspace", - "ResourceTypeWorkspaceBuild", - "ResourceTypeGitSSHKey", - "ResourceTypeAPIKey", - "ResourceTypeGroup", - "ResourceTypeLicense", - "ResourceTypeConvertLogin", - "ResourceTypeHealthSettings", - "ResourceTypeNotificationsSettings", - "ResourceTypeWorkspaceProxy", - "ResourceTypeOrganization", - "ResourceTypeOAuth2ProviderApp", - "ResourceTypeOAuth2ProviderAppSecret", - "ResourceTypeCustomRole" - ] - }, - "codersdk.Response": { - "type": "object", - "properties": { - "detail": { - "description": "Detail is a debug message that provides further insight into why the\naction failed. This information can be technical and a regular golang\nerr.Error() text.\n- \"database: too many open connections\"\n- \"stat: too many open files\"", - "type": "string" - }, - "message": { - "description": "Message is an actionable message that depicts actions the request took.\nThese messages should be fully formed sentences with proper punctuation.\nExamples:\n- \"A user has been created.\"\n- \"Failed to create a user.\"", - "type": "string" - }, - "validations": { - "description": "Validations are form field-specific friendly error messages. They will be\nshown on a form field in the UI. These can also be used to add additional\ncontext if there is a set of errors in the primary 'Message'.", - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.ValidationError" - } - } - } - }, - "codersdk.Role": { - "type": "object", - "properties": { - "display_name": { - "type": "string" - }, - "name": { - "type": "string" - }, - "organization_id": { - "type": "string", - "format": "uuid" - }, - "organization_permissions": { - "description": "OrganizationPermissions are specific for the organization in the field 'OrganizationID' above.", - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Permission" - } - }, - "site_permissions": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Permission" - } - }, - "user_permissions": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Permission" - } - } - } - }, - "codersdk.SSHConfig": { - "type": "object", - "properties": { - "deploymentName": { - "description": "DeploymentName is the config-ssh Hostname prefix", - "type": "string" - }, - "sshconfigOptions": { - "description": "SSHConfigOptions are additional options to add to the ssh config file.\nThis will override defaults.", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "codersdk.SSHConfigResponse": { - "type": "object", - "properties": { - "hostname_prefix": { - "type": "string" - }, - "ssh_config_options": { - "type": "object", - "additionalProperties": { - "type": "string" - } - } - } - }, - "codersdk.SessionCountDeploymentStats": { - "type": "object", - "properties": { - "jetbrains": { - "type": "integer" - }, - "reconnecting_pty": { - "type": "integer" - }, - "ssh": { - "type": "integer" - }, - "vscode": { - "type": "integer" - } - } - }, - "codersdk.SessionLifetime": { - "type": "object", - "properties": { - "default_duration": { - "description": "DefaultDuration is for api keys, not tokens.", - "type": "integer" - }, - "disable_expiry_refresh": { - "description": "DisableExpiryRefresh will disable automatically refreshing api\nkeys when they are used from the api. This means the api key lifetime at\ncreation is the lifetime of the api key.", - "type": "boolean" - }, - "max_token_lifetime": { - "type": "integer" - } - } - }, - "codersdk.SlimRole": { - "type": "object", - "properties": { - "display_name": { - "type": "string" - }, - "name": { - "type": "string" - }, - "organization_id": { - "type": "string" - } - } - }, - "codersdk.SupportConfig": { - "type": "object", - "properties": { - "links": { - "$ref": "#/definitions/serpent.Struct-array_codersdk_LinkConfig" - } - } - }, - "codersdk.SwaggerConfig": { - "type": "object", - "properties": { - "enable": { - "type": "boolean" - } - } - }, - "codersdk.TLSConfig": { - "type": "object", - "properties": { - "address": { - "$ref": "#/definitions/serpent.HostPort" - }, - "allow_insecure_ciphers": { - "type": "boolean" - }, - "cert_file": { - "type": "array", - "items": { - "type": "string" - } - }, - "client_auth": { - "type": "string" - }, - "client_ca_file": { - "type": "string" - }, - "client_cert_file": { - "type": "string" - }, - "client_key_file": { - "type": "string" - }, - "enable": { - "type": "boolean" - }, - "key_file": { - "type": "array", - "items": { - "type": "string" - } - }, - "min_version": { - "type": "string" - }, - "redirect_http": { - "type": "boolean" - }, - "supported_ciphers": { - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "codersdk.TelemetryConfig": { - "type": "object", - "properties": { - "enable": { - "type": "boolean" - }, - "trace": { - "type": "boolean" - }, - "url": { - "$ref": "#/definitions/serpent.URL" - } - } - }, - "codersdk.Template": { - "type": "object", - "properties": { - "active_user_count": { - "description": "ActiveUserCount is set to -1 when loading.", - "type": "integer" - }, - "active_version_id": { - "type": "string", - "format": "uuid" - }, - "activity_bump_ms": { - "type": "integer" - }, - "allow_user_autostart": { - "description": "AllowUserAutostart and AllowUserAutostop are enterprise-only. Their\nvalues are only used if your license is entitled to use the advanced\ntemplate scheduling feature.", - "type": "boolean" - }, - "allow_user_autostop": { - "type": "boolean" - }, - "allow_user_cancel_workspace_jobs": { - "type": "boolean" - }, - "autostart_requirement": { - "$ref": "#/definitions/codersdk.TemplateAutostartRequirement" - }, - "autostop_requirement": { - "description": "AutostopRequirement and AutostartRequirement are enterprise features. Its\nvalue is only used if your license is entitled to use the advanced template\nscheduling feature.", - "allOf": [ - { - "$ref": "#/definitions/codersdk.TemplateAutostopRequirement" - } - ] - }, - "build_time_stats": { - "$ref": "#/definitions/codersdk.TemplateBuildTimeStats" - }, - "created_at": { - "type": "string", - "format": "date-time" - }, - "created_by_id": { - "type": "string", - "format": "uuid" - }, - "created_by_name": { - "type": "string" - }, - "default_ttl_ms": { - "type": "integer" - }, - "deprecated": { - "type": "boolean" - }, - "deprecation_message": { - "type": "string" - }, - "description": { - "type": "string" - }, - "display_name": { - "type": "string" - }, - "failure_ttl_ms": { - "description": "FailureTTLMillis, TimeTilDormantMillis, and TimeTilDormantAutoDeleteMillis are enterprise-only. Their\nvalues are used if your license is entitled to use the advanced\ntemplate scheduling feature.", - "type": "integer" - }, - "icon": { - "type": "string" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "max_port_share_level": { - "$ref": "#/definitions/codersdk.WorkspaceAgentPortShareLevel" - }, - "name": { - "type": "string" - }, - "organization_display_name": { - "type": "string" - }, - "organization_icon": { - "type": "string" - }, - "organization_id": { - "type": "string", - "format": "uuid" - }, - "organization_name": { - "type": "string", - "format": "url" - }, - "provisioner": { - "type": "string", - "enum": ["terraform"] - }, - "require_active_version": { - "description": "RequireActiveVersion mandates that workspaces are built with the active\ntemplate version.", - "type": "boolean" - }, - "time_til_dormant_autodelete_ms": { - "type": "integer" - }, - "time_til_dormant_ms": { - "type": "integer" - }, - "updated_at": { - "type": "string", - "format": "date-time" - } - } - }, - "codersdk.TemplateAppUsage": { - "type": "object", - "properties": { - "display_name": { - "type": "string", - "example": "Visual Studio Code" - }, - "icon": { - "type": "string" - }, - "seconds": { - "type": "integer", - "example": 80500 - }, - "slug": { - "type": "string", - "example": "vscode" - }, - "template_ids": { - "type": "array", - "items": { - "type": "string", - "format": "uuid" - } - }, - "times_used": { - "type": "integer", - "example": 2 - }, - "type": { - "allOf": [ - { - "$ref": "#/definitions/codersdk.TemplateAppsType" - } - ], - "example": "builtin" - } - } - }, - "codersdk.TemplateAppsType": { - "type": "string", - "enum": ["builtin", "app"], - "x-enum-varnames": ["TemplateAppsTypeBuiltin", "TemplateAppsTypeApp"] - }, - "codersdk.TemplateAutostartRequirement": { - "type": "object", - "properties": { - "days_of_week": { - "description": "DaysOfWeek is a list of days of the week in which autostart is allowed\nto happen. If no days are specified, autostart is not allowed.", - "type": "array", - "items": { - "type": "string", - "enum": [ - "monday", - "tuesday", - "wednesday", - "thursday", - "friday", - "saturday", - "sunday" - ] - } - } - } - }, - "codersdk.TemplateAutostopRequirement": { - "type": "object", - "properties": { - "days_of_week": { - "description": "DaysOfWeek is a list of days of the week on which restarts are required.\nRestarts happen within the user's quiet hours (in their configured\ntimezone). If no days are specified, restarts are not required. Weekdays\ncannot be specified twice.\n\nRestarts will only happen on weekdays in this list on weeks which line up\nwith Weeks.", - "type": "array", - "items": { - "type": "string", - "enum": [ - "monday", - "tuesday", - "wednesday", - "thursday", - "friday", - "saturday", - "sunday" - ] - } - }, - "weeks": { - "description": "Weeks is the number of weeks between required restarts. Weeks are synced\nacross all workspaces (and Coder deployments) using modulo math on a\nhardcoded epoch week of January 2nd, 2023 (the first Monday of 2023).\nValues of 0 or 1 indicate weekly restarts. Values of 2 indicate\nfortnightly restarts, etc.", - "type": "integer" - } - } - }, - "codersdk.TemplateBuildTimeStats": { - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/codersdk.TransitionStats" - } - }, - "codersdk.TemplateExample": { - "type": "object", - "properties": { - "description": { - "type": "string" - }, - "icon": { - "type": "string" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "markdown": { - "type": "string" - }, - "name": { - "type": "string" - }, - "tags": { - "type": "array", - "items": { - "type": "string" - } - }, - "url": { - "type": "string" - } - } - }, - "codersdk.TemplateInsightsIntervalReport": { - "type": "object", - "properties": { - "active_users": { - "type": "integer", - "example": 14 - }, - "end_time": { - "type": "string", - "format": "date-time" - }, - "interval": { - "allOf": [ - { - "$ref": "#/definitions/codersdk.InsightsReportInterval" - } - ], - "example": "week" - }, - "start_time": { - "type": "string", - "format": "date-time" - }, - "template_ids": { - "type": "array", - "items": { - "type": "string", - "format": "uuid" - } - } - } - }, - "codersdk.TemplateInsightsReport": { - "type": "object", - "properties": { - "active_users": { - "type": "integer", - "example": 22 - }, - "apps_usage": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.TemplateAppUsage" - } - }, - "end_time": { - "type": "string", - "format": "date-time" - }, - "parameters_usage": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.TemplateParameterUsage" - } - }, - "start_time": { - "type": "string", - "format": "date-time" - }, - "template_ids": { - "type": "array", - "items": { - "type": "string", - "format": "uuid" - } - } - } - }, - "codersdk.TemplateInsightsResponse": { - "type": "object", - "properties": { - "interval_reports": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.TemplateInsightsIntervalReport" - } - }, - "report": { - "$ref": "#/definitions/codersdk.TemplateInsightsReport" - } - } - }, - "codersdk.TemplateParameterUsage": { - "type": "object", - "properties": { - "description": { - "type": "string" - }, - "display_name": { - "type": "string" - }, - "name": { - "type": "string" - }, - "options": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.TemplateVersionParameterOption" - } - }, - "template_ids": { - "type": "array", - "items": { - "type": "string", - "format": "uuid" - } - }, - "type": { - "type": "string" - }, - "values": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.TemplateParameterValue" - } - } - } - }, - "codersdk.TemplateParameterValue": { - "type": "object", - "properties": { - "count": { - "type": "integer" - }, - "value": { - "type": "string" - } - } - }, - "codersdk.TemplateRole": { - "type": "string", - "enum": ["admin", "use", ""], - "x-enum-varnames": [ - "TemplateRoleAdmin", - "TemplateRoleUse", - "TemplateRoleDeleted" - ] - }, - "codersdk.TemplateUser": { - "type": "object", - "required": ["created_at", "email", "id", "username"], - "properties": { - "avatar_url": { - "type": "string", - "format": "uri" - }, - "created_at": { - "type": "string", - "format": "date-time" - }, - "email": { - "type": "string", - "format": "email" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "last_seen_at": { - "type": "string", - "format": "date-time" - }, - "login_type": { - "$ref": "#/definitions/codersdk.LoginType" - }, - "name": { - "type": "string" - }, - "organization_ids": { - "type": "array", - "items": { - "type": "string", - "format": "uuid" - } - }, - "role": { - "enum": ["admin", "use"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.TemplateRole" - } - ] - }, - "roles": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.SlimRole" - } - }, - "status": { - "enum": ["active", "suspended"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.UserStatus" - } - ] - }, - "theme_preference": { - "type": "string" - }, - "updated_at": { - "type": "string", - "format": "date-time" - }, - "username": { - "type": "string" - } - } - }, - "codersdk.TemplateVersion": { - "type": "object", - "properties": { - "archived": { - "type": "boolean" - }, - "created_at": { - "type": "string", - "format": "date-time" - }, - "created_by": { - "$ref": "#/definitions/codersdk.MinimalUser" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "job": { - "$ref": "#/definitions/codersdk.ProvisionerJob" - }, - "message": { - "type": "string" - }, - "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" - }, - "warnings": { - "type": "array", - "items": { - "enum": ["DEPRECATED_PARAMETERS"], - "$ref": "#/definitions/codersdk.TemplateVersionWarning" - } - } - } - }, - "codersdk.TemplateVersionExternalAuth": { - "type": "object", - "properties": { - "authenticate_url": { - "type": "string" - }, - "authenticated": { - "type": "boolean" - }, - "display_icon": { - "type": "string" - }, - "display_name": { - "type": "string" - }, - "id": { - "type": "string" - }, - "optional": { - "type": "boolean" - }, - "type": { - "type": "string" - } - } - }, - "codersdk.TemplateVersionParameter": { - "type": "object", - "properties": { - "default_value": { - "type": "string" - }, - "description": { - "type": "string" - }, - "description_plaintext": { - "type": "string" - }, - "display_name": { - "type": "string" - }, - "ephemeral": { - "type": "boolean" - }, - "icon": { - "type": "string" - }, - "mutable": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "options": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.TemplateVersionParameterOption" - } - }, - "required": { - "type": "boolean" - }, - "type": { - "type": "string", - "enum": ["string", "number", "bool", "list(string)"] - }, - "validation_error": { - "type": "string" - }, - "validation_max": { - "type": "integer" - }, - "validation_min": { - "type": "integer" - }, - "validation_monotonic": { - "enum": ["increasing", "decreasing"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.ValidationMonotonicOrder" - } - ] - }, - "validation_regex": { - "type": "string" - } - } - }, - "codersdk.TemplateVersionParameterOption": { - "type": "object", - "properties": { - "description": { - "type": "string" - }, - "icon": { - "type": "string" - }, - "name": { - "type": "string" - }, - "value": { - "type": "string" - } - } - }, - "codersdk.TemplateVersionVariable": { - "type": "object", - "properties": { - "default_value": { - "type": "string" - }, - "description": { - "type": "string" - }, - "name": { - "type": "string" - }, - "required": { - "type": "boolean" - }, - "sensitive": { - "type": "boolean" - }, - "type": { - "type": "string", - "enum": ["string", "number", "bool"] - }, - "value": { - "type": "string" - } - } - }, - "codersdk.TemplateVersionWarning": { - "type": "string", - "enum": ["UNSUPPORTED_WORKSPACES"], - "x-enum-varnames": ["TemplateVersionWarningUnsupportedWorkspaces"] - }, - "codersdk.TokenConfig": { - "type": "object", - "properties": { - "max_token_lifetime": { - "type": "integer" - } - } - }, - "codersdk.TraceConfig": { - "type": "object", - "properties": { - "capture_logs": { - "type": "boolean" - }, - "data_dog": { - "type": "boolean" - }, - "enable": { - "type": "boolean" - }, - "honeycomb_api_key": { - "type": "string" - } - } - }, - "codersdk.TransitionStats": { - "type": "object", - "properties": { - "p50": { - "type": "integer", - "example": 123 - }, - "p95": { - "type": "integer", - "example": 146 - } - } - }, - "codersdk.UpdateActiveTemplateVersion": { - "type": "object", - "required": ["id"], - "properties": { - "id": { - "type": "string", - "format": "uuid" - } - } - }, - "codersdk.UpdateAppearanceConfig": { - "type": "object", - "properties": { - "announcement_banners": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.BannerConfig" - } - }, - "application_name": { - "type": "string" - }, - "logo_url": { - "type": "string" - }, - "service_banner": { - "description": "Deprecated: ServiceBanner has been replaced by AnnouncementBanners.", - "allOf": [ - { - "$ref": "#/definitions/codersdk.BannerConfig" - } - ] - } - } - }, - "codersdk.UpdateCheckResponse": { - "type": "object", - "properties": { - "current": { - "description": "Current indicates whether the server version is the same as the latest.", - "type": "boolean" - }, - "url": { - "description": "URL to download the latest release of Coder.", - "type": "string" - }, - "version": { - "description": "Version is the semantic version for the latest release of Coder.", - "type": "string" - } - } - }, - "codersdk.UpdateOrganizationRequest": { - "type": "object", - "properties": { - "description": { - "type": "string" - }, - "display_name": { - "type": "string" - }, - "icon": { - "type": "string" - }, - "name": { - "type": "string" - } - } - }, - "codersdk.UpdateRoles": { - "type": "object", - "properties": { - "roles": { - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "codersdk.UpdateTemplateACL": { - "type": "object", - "properties": { - "group_perms": { - "description": "GroupPerms should be a mapping of group id to role.", - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/codersdk.TemplateRole" - }, - "example": { - "8bd26b20-f3e8-48be-a903-46bb920cf671": "use", - "\u003cuser_id\u003e\u003e": "admin" - } - }, - "user_perms": { - "description": "UserPerms should be a mapping of user id to role. The user id must be the\nuuid of the user, not a username or email address.", - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/codersdk.TemplateRole" - }, - "example": { - "4df59e74-c027-470b-ab4d-cbba8963a5e9": "use", - "\u003cgroup_id\u003e": "admin" - } - } - } - }, - "codersdk.UpdateUserAppearanceSettingsRequest": { - "type": "object", - "required": ["theme_preference"], - "properties": { - "theme_preference": { - "type": "string" - } - } - }, - "codersdk.UpdateUserNotificationPreferences": { - "type": "object", - "properties": { - "template_disabled_map": { - "type": "object", - "additionalProperties": { - "type": "boolean" - } - } - } - }, - "codersdk.UpdateUserPasswordRequest": { - "type": "object", - "required": ["password"], - "properties": { - "old_password": { - "type": "string" - }, - "password": { - "type": "string" - } - } - }, - "codersdk.UpdateUserProfileRequest": { - "type": "object", - "required": ["username"], - "properties": { - "name": { - "type": "string" - }, - "username": { - "type": "string" - } - } - }, - "codersdk.UpdateUserQuietHoursScheduleRequest": { - "type": "object", - "required": ["schedule"], - "properties": { - "schedule": { - "description": "Schedule is a cron expression that defines when the user's quiet hours\nwindow is. Schedule must not be empty. For new users, the schedule is set\nto 2am in their browser or computer's timezone. The schedule denotes the\nbeginning of a 4 hour window where the workspace is allowed to\nautomatically stop or restart due to maintenance or template schedule.\n\nThe schedule must be daily with a single time, and should have a timezone\nspecified via a CRON_TZ prefix (otherwise UTC will be used).\n\nIf the schedule is empty, the user will be updated to use the default\nschedule.", - "type": "string" - } - } - }, - "codersdk.UpdateWorkspaceAutomaticUpdatesRequest": { - "type": "object", - "properties": { - "automatic_updates": { - "$ref": "#/definitions/codersdk.AutomaticUpdates" - } - } - }, - "codersdk.UpdateWorkspaceAutostartRequest": { - "type": "object", - "properties": { - "schedule": { - "description": "Schedule is expected to be of the form `CRON_TZ=\u003cIANA Timezone\u003e \u003cmin\u003e \u003chour\u003e * * \u003cdow\u003e`\nExample: `CRON_TZ=US/Central 30 9 * * 1-5` represents 0930 in the timezone US/Central\non weekdays (Mon-Fri). `CRON_TZ` defaults to UTC if not present.", - "type": "string" - } - } - }, - "codersdk.UpdateWorkspaceDormancy": { - "type": "object", - "properties": { - "dormant": { - "type": "boolean" - } - } - }, - "codersdk.UpdateWorkspaceRequest": { - "type": "object", - "properties": { - "name": { - "type": "string" - } - } - }, - "codersdk.UpdateWorkspaceTTLRequest": { - "type": "object", - "properties": { - "ttl_ms": { - "type": "integer" - } - } - }, - "codersdk.UploadResponse": { - "type": "object", - "properties": { - "hash": { - "type": "string", - "format": "uuid" - } - } - }, - "codersdk.UpsertWorkspaceAgentPortShareRequest": { - "type": "object", - "properties": { - "agent_name": { - "type": "string" - }, - "port": { - "type": "integer" - }, - "protocol": { - "enum": ["http", "https"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.WorkspaceAgentPortShareProtocol" - } - ] - }, - "share_level": { - "enum": ["owner", "authenticated", "public"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.WorkspaceAgentPortShareLevel" - } - ] - } - } - }, - "codersdk.UsageAppName": { - "type": "string", - "enum": ["vscode", "jetbrains", "reconnecting-pty", "ssh"], - "x-enum-varnames": [ - "UsageAppNameVscode", - "UsageAppNameJetbrains", - "UsageAppNameReconnectingPty", - "UsageAppNameSSH" - ] - }, - "codersdk.User": { - "type": "object", - "required": ["created_at", "email", "id", "username"], - "properties": { - "avatar_url": { - "type": "string", - "format": "uri" - }, - "created_at": { - "type": "string", - "format": "date-time" - }, - "email": { - "type": "string", - "format": "email" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "last_seen_at": { - "type": "string", - "format": "date-time" - }, - "login_type": { - "$ref": "#/definitions/codersdk.LoginType" - }, - "name": { - "type": "string" - }, - "organization_ids": { - "type": "array", - "items": { - "type": "string", - "format": "uuid" - } - }, - "roles": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.SlimRole" - } - }, - "status": { - "enum": ["active", "suspended"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.UserStatus" - } - ] - }, - "theme_preference": { - "type": "string" - }, - "updated_at": { - "type": "string", - "format": "date-time" - }, - "username": { - "type": "string" - } - } - }, - "codersdk.UserActivity": { - "type": "object", - "properties": { - "avatar_url": { - "type": "string", - "format": "uri" - }, - "seconds": { - "type": "integer", - "example": 80500 - }, - "template_ids": { - "type": "array", - "items": { - "type": "string", - "format": "uuid" - } - }, - "user_id": { - "type": "string", - "format": "uuid" - }, - "username": { - "type": "string" - } - } - }, - "codersdk.UserActivityInsightsReport": { - "type": "object", - "properties": { - "end_time": { - "type": "string", - "format": "date-time" - }, - "start_time": { - "type": "string", - "format": "date-time" - }, - "template_ids": { - "type": "array", - "items": { - "type": "string", - "format": "uuid" - } - }, - "users": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.UserActivity" - } - } - } - }, - "codersdk.UserActivityInsightsResponse": { - "type": "object", - "properties": { - "report": { - "$ref": "#/definitions/codersdk.UserActivityInsightsReport" - } - } - }, - "codersdk.UserLatency": { - "type": "object", - "properties": { - "avatar_url": { - "type": "string", - "format": "uri" - }, - "latency_ms": { - "$ref": "#/definitions/codersdk.ConnectionLatency" - }, - "template_ids": { - "type": "array", - "items": { - "type": "string", - "format": "uuid" - } - }, - "user_id": { - "type": "string", - "format": "uuid" - }, - "username": { - "type": "string" - } - } - }, - "codersdk.UserLatencyInsightsReport": { - "type": "object", - "properties": { - "end_time": { - "type": "string", - "format": "date-time" - }, - "start_time": { - "type": "string", - "format": "date-time" - }, - "template_ids": { - "type": "array", - "items": { - "type": "string", - "format": "uuid" - } - }, - "users": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.UserLatency" - } - } - } - }, - "codersdk.UserLatencyInsightsResponse": { - "type": "object", - "properties": { - "report": { - "$ref": "#/definitions/codersdk.UserLatencyInsightsReport" - } - } - }, - "codersdk.UserLoginType": { - "type": "object", - "properties": { - "login_type": { - "$ref": "#/definitions/codersdk.LoginType" - } - } - }, - "codersdk.UserParameter": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "value": { - "type": "string" - } - } - }, - "codersdk.UserQuietHoursScheduleConfig": { - "type": "object", - "properties": { - "allow_user_custom": { - "type": "boolean" - }, - "default_schedule": { - "type": "string" - } - } - }, - "codersdk.UserQuietHoursScheduleResponse": { - "type": "object", - "properties": { - "next": { - "description": "Next is the next time that the quiet hours window will start.", - "type": "string", - "format": "date-time" - }, - "raw_schedule": { - "type": "string" - }, - "time": { - "description": "Time is the time of day that the quiet hours window starts in the given\nTimezone each day.", - "type": "string" - }, - "timezone": { - "description": "raw format from the cron expression, UTC if unspecified", - "type": "string" - }, - "user_can_set": { - "description": "UserCanSet is true if the user is allowed to set their own quiet hours\nschedule. If false, the user cannot set a custom schedule and the default\nschedule will always be used.", - "type": "boolean" - }, - "user_set": { - "description": "UserSet is true if the user has set their own quiet hours schedule. If\nfalse, the user is using the default schedule.", - "type": "boolean" - } - } - }, - "codersdk.UserStatus": { - "type": "string", - "enum": ["active", "dormant", "suspended"], - "x-enum-varnames": [ - "UserStatusActive", - "UserStatusDormant", - "UserStatusSuspended" - ] - }, - "codersdk.ValidationError": { - "type": "object", - "required": ["detail", "field"], - "properties": { - "detail": { - "type": "string" - }, - "field": { - "type": "string" - } - } - }, - "codersdk.ValidationMonotonicOrder": { - "type": "string", - "enum": ["increasing", "decreasing"], - "x-enum-varnames": [ - "MonotonicOrderIncreasing", - "MonotonicOrderDecreasing" - ] - }, - "codersdk.VariableValue": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "value": { - "type": "string" - } - } - }, - "codersdk.Workspace": { - "type": "object", - "properties": { - "allow_renames": { - "type": "boolean" - }, - "automatic_updates": { - "enum": ["always", "never"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.AutomaticUpdates" - } - ] - }, - "autostart_schedule": { - "type": "string" - }, - "created_at": { - "type": "string", - "format": "date-time" - }, - "deleting_at": { - "description": "DeletingAt indicates the time at which the workspace will be permanently deleted.\nA workspace is eligible for deletion if it is dormant (a non-nil dormant_at value)\nand a value has been specified for time_til_dormant_autodelete on its template.", - "type": "string", - "format": "date-time" - }, - "dormant_at": { - "description": "DormantAt being non-nil indicates a workspace that is dormant.\nA dormant workspace is no longer accessible must be activated.\nIt is subject to deletion if it breaches\nthe duration of the time_til_ field on its template.", - "type": "string", - "format": "date-time" - }, - "favorite": { - "type": "boolean" - }, - "health": { - "description": "Health shows the health of the workspace and information about\nwhat is causing an unhealthy status.", - "allOf": [ - { - "$ref": "#/definitions/codersdk.WorkspaceHealth" - } - ] - }, - "id": { - "type": "string", - "format": "uuid" - }, - "last_used_at": { - "type": "string", - "format": "date-time" - }, - "latest_build": { - "$ref": "#/definitions/codersdk.WorkspaceBuild" - }, - "name": { - "type": "string" - }, - "organization_id": { - "type": "string", - "format": "uuid" - }, - "organization_name": { - "type": "string" - }, - "outdated": { - "type": "boolean" - }, - "owner_avatar_url": { - "type": "string" - }, - "owner_id": { - "type": "string", - "format": "uuid" - }, - "owner_name": { - "type": "string" - }, - "template_active_version_id": { - "type": "string", - "format": "uuid" - }, - "template_allow_user_cancel_workspace_jobs": { - "type": "boolean" - }, - "template_display_name": { - "type": "string" - }, - "template_icon": { - "type": "string" - }, - "template_id": { - "type": "string", - "format": "uuid" - }, - "template_name": { - "type": "string" - }, - "template_require_active_version": { - "type": "boolean" - }, - "ttl_ms": { - "type": "integer" - }, - "updated_at": { - "type": "string", - "format": "date-time" - } - } - }, - "codersdk.WorkspaceAgent": { - "type": "object", - "properties": { - "api_version": { - "type": "string" - }, - "apps": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceApp" - } - }, - "architecture": { - "type": "string" - }, - "connection_timeout_seconds": { - "type": "integer" - }, - "created_at": { - "type": "string", - "format": "date-time" - }, - "directory": { - "type": "string" - }, - "disconnected_at": { - "type": "string", - "format": "date-time" - }, - "display_apps": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.DisplayApp" - } - }, - "environment_variables": { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "expanded_directory": { - "type": "string" - }, - "first_connected_at": { - "type": "string", - "format": "date-time" - }, - "health": { - "description": "Health reports the health of the agent.", - "allOf": [ - { - "$ref": "#/definitions/codersdk.WorkspaceAgentHealth" - } - ] - }, - "id": { - "type": "string", - "format": "uuid" - }, - "instance_id": { - "type": "string" - }, - "last_connected_at": { - "type": "string", - "format": "date-time" - }, - "latency": { - "description": "DERPLatency is mapped by region name (e.g. \"New York City\", \"Seattle\").", - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/codersdk.DERPRegion" - } - }, - "lifecycle_state": { - "$ref": "#/definitions/codersdk.WorkspaceAgentLifecycle" - }, - "log_sources": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceAgentLogSource" - } - }, - "logs_length": { - "type": "integer" - }, - "logs_overflowed": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "operating_system": { - "type": "string" - }, - "ready_at": { - "type": "string", - "format": "date-time" - }, - "resource_id": { - "type": "string", - "format": "uuid" - }, - "scripts": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceAgentScript" - } - }, - "started_at": { - "type": "string", - "format": "date-time" - }, - "startup_script_behavior": { - "description": "StartupScriptBehavior is a legacy field that is deprecated in favor\nof the `coder_script` resource. It's only referenced by old clients.\nDeprecated: Remove in the future!", - "allOf": [ - { - "$ref": "#/definitions/codersdk.WorkspaceAgentStartupScriptBehavior" - } - ] - }, - "status": { - "$ref": "#/definitions/codersdk.WorkspaceAgentStatus" - }, - "subsystems": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.AgentSubsystem" - } - }, - "troubleshooting_url": { - "type": "string" - }, - "updated_at": { - "type": "string", - "format": "date-time" - }, - "version": { - "type": "string" - } - } - }, - "codersdk.WorkspaceAgentHealth": { - "type": "object", - "properties": { - "healthy": { - "description": "Healthy is true if the agent is healthy.", - "type": "boolean", - "example": false - }, - "reason": { - "description": "Reason is a human-readable explanation of the agent's health. It is empty if Healthy is true.", - "type": "string", - "example": "agent has lost connection" - } - } - }, - "codersdk.WorkspaceAgentLifecycle": { - "type": "string", - "enum": [ - "created", - "starting", - "start_timeout", - "start_error", - "ready", - "shutting_down", - "shutdown_timeout", - "shutdown_error", - "off" - ], - "x-enum-varnames": [ - "WorkspaceAgentLifecycleCreated", - "WorkspaceAgentLifecycleStarting", - "WorkspaceAgentLifecycleStartTimeout", - "WorkspaceAgentLifecycleStartError", - "WorkspaceAgentLifecycleReady", - "WorkspaceAgentLifecycleShuttingDown", - "WorkspaceAgentLifecycleShutdownTimeout", - "WorkspaceAgentLifecycleShutdownError", - "WorkspaceAgentLifecycleOff" - ] - }, - "codersdk.WorkspaceAgentListeningPort": { - "type": "object", - "properties": { - "network": { - "description": "only \"tcp\" at the moment", - "type": "string" - }, - "port": { - "type": "integer" - }, - "process_name": { - "description": "may be empty", - "type": "string" - } - } - }, - "codersdk.WorkspaceAgentListeningPortsResponse": { - "type": "object", - "properties": { - "ports": { - "description": "If there are no ports in the list, nothing should be displayed in the UI.\nThere must not be a \"no ports available\" message or anything similar, as\nthere will always be no ports displayed on platforms where our port\ndetection logic is unsupported.", - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceAgentListeningPort" - } - } - } - }, - "codersdk.WorkspaceAgentLog": { - "type": "object", - "properties": { - "created_at": { - "type": "string", - "format": "date-time" - }, - "id": { - "type": "integer" - }, - "level": { - "$ref": "#/definitions/codersdk.LogLevel" - }, - "output": { - "type": "string" - }, - "source_id": { - "type": "string", - "format": "uuid" - } - } - }, - "codersdk.WorkspaceAgentLogSource": { - "type": "object", - "properties": { - "created_at": { - "type": "string", - "format": "date-time" - }, - "display_name": { - "type": "string" - }, - "icon": { - "type": "string" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "workspace_agent_id": { - "type": "string", - "format": "uuid" - } - } - }, - "codersdk.WorkspaceAgentPortShare": { - "type": "object", - "properties": { - "agent_name": { - "type": "string" - }, - "port": { - "type": "integer" - }, - "protocol": { - "enum": ["http", "https"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.WorkspaceAgentPortShareProtocol" - } - ] - }, - "share_level": { - "enum": ["owner", "authenticated", "public"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.WorkspaceAgentPortShareLevel" - } - ] - }, - "workspace_id": { - "type": "string", - "format": "uuid" - } - } - }, - "codersdk.WorkspaceAgentPortShareLevel": { - "type": "string", - "enum": ["owner", "authenticated", "public"], - "x-enum-varnames": [ - "WorkspaceAgentPortShareLevelOwner", - "WorkspaceAgentPortShareLevelAuthenticated", - "WorkspaceAgentPortShareLevelPublic" - ] - }, - "codersdk.WorkspaceAgentPortShareProtocol": { - "type": "string", - "enum": ["http", "https"], - "x-enum-varnames": [ - "WorkspaceAgentPortShareProtocolHTTP", - "WorkspaceAgentPortShareProtocolHTTPS" - ] - }, - "codersdk.WorkspaceAgentPortShares": { - "type": "object", - "properties": { - "shares": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceAgentPortShare" - } - } - } - }, - "codersdk.WorkspaceAgentScript": { - "type": "object", - "properties": { - "cron": { - "type": "string" - }, - "log_path": { - "type": "string" - }, - "log_source_id": { - "type": "string", - "format": "uuid" - }, - "run_on_start": { - "type": "boolean" - }, - "run_on_stop": { - "type": "boolean" - }, - "script": { - "type": "string" - }, - "start_blocks_login": { - "type": "boolean" - }, - "timeout": { - "type": "integer" - } - } - }, - "codersdk.WorkspaceAgentStartupScriptBehavior": { - "type": "string", - "enum": ["blocking", "non-blocking"], - "x-enum-varnames": [ - "WorkspaceAgentStartupScriptBehaviorBlocking", - "WorkspaceAgentStartupScriptBehaviorNonBlocking" - ] - }, - "codersdk.WorkspaceAgentStatus": { - "type": "string", - "enum": ["connecting", "connected", "disconnected", "timeout"], - "x-enum-varnames": [ - "WorkspaceAgentConnecting", - "WorkspaceAgentConnected", - "WorkspaceAgentDisconnected", - "WorkspaceAgentTimeout" - ] - }, - "codersdk.WorkspaceApp": { - "type": "object", - "properties": { - "command": { - "type": "string" - }, - "display_name": { - "description": "DisplayName is a friendly name for the app.", - "type": "string" - }, - "external": { - "description": "External specifies whether the URL should be opened externally on\nthe client or not.", - "type": "boolean" - }, - "health": { - "$ref": "#/definitions/codersdk.WorkspaceAppHealth" - }, - "healthcheck": { - "description": "Healthcheck specifies the configuration for checking app health.", - "allOf": [ - { - "$ref": "#/definitions/codersdk.Healthcheck" - } - ] - }, - "icon": { - "description": "Icon is a relative path or external URL that specifies\nan icon to be displayed in the dashboard.", - "type": "string" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "sharing_level": { - "enum": ["owner", "authenticated", "public"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.WorkspaceAppSharingLevel" - } - ] - }, - "slug": { - "description": "Slug is a unique identifier within the agent.", - "type": "string" - }, - "subdomain": { - "description": "Subdomain denotes whether the app should be accessed via a path on the\n`coder server` or via a hostname-based dev URL. If this is set to true\nand there is no app wildcard configured on the server, the app will not\nbe accessible in the UI.", - "type": "boolean" - }, - "subdomain_name": { - "description": "SubdomainName is the application domain exposed on the `coder server`.", - "type": "string" - }, - "url": { - "description": "URL is the address being proxied to inside the workspace.\nIf external is specified, this will be opened on the client.", - "type": "string" - } - } - }, - "codersdk.WorkspaceAppHealth": { - "type": "string", - "enum": ["disabled", "initializing", "healthy", "unhealthy"], - "x-enum-varnames": [ - "WorkspaceAppHealthDisabled", - "WorkspaceAppHealthInitializing", - "WorkspaceAppHealthHealthy", - "WorkspaceAppHealthUnhealthy" - ] - }, - "codersdk.WorkspaceAppSharingLevel": { - "type": "string", - "enum": ["owner", "authenticated", "public"], - "x-enum-varnames": [ - "WorkspaceAppSharingLevelOwner", - "WorkspaceAppSharingLevelAuthenticated", - "WorkspaceAppSharingLevelPublic" - ] - }, - "codersdk.WorkspaceBuild": { - "type": "object", - "properties": { - "build_number": { - "type": "integer" - }, - "created_at": { - "type": "string", - "format": "date-time" - }, - "daily_cost": { - "type": "integer" - }, - "deadline": { - "type": "string", - "format": "date-time" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "initiator_id": { - "type": "string", - "format": "uuid" - }, - "initiator_name": { - "type": "string" - }, - "job": { - "$ref": "#/definitions/codersdk.ProvisionerJob" - }, - "max_deadline": { - "type": "string", - "format": "date-time" - }, - "reason": { - "enum": ["initiator", "autostart", "autostop"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.BuildReason" - } - ] - }, - "resources": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceResource" - } - }, - "status": { - "enum": [ - "pending", - "starting", - "running", - "stopping", - "stopped", - "failed", - "canceling", - "canceled", - "deleting", - "deleted" - ], - "allOf": [ - { - "$ref": "#/definitions/codersdk.WorkspaceStatus" - } - ] - }, - "template_version_id": { - "type": "string", - "format": "uuid" - }, - "template_version_name": { - "type": "string" - }, - "transition": { - "enum": ["start", "stop", "delete"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.WorkspaceTransition" - } - ] - }, - "updated_at": { - "type": "string", - "format": "date-time" - }, - "workspace_id": { - "type": "string", - "format": "uuid" - }, - "workspace_name": { - "type": "string" - }, - "workspace_owner_avatar_url": { - "type": "string" - }, - "workspace_owner_id": { - "type": "string", - "format": "uuid" - }, - "workspace_owner_name": { - "type": "string" - } - } - }, - "codersdk.WorkspaceBuildParameter": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "value": { - "type": "string" - } - } - }, - "codersdk.WorkspaceConnectionLatencyMS": { - "type": "object", - "properties": { - "p50": { - "type": "number" - }, - "p95": { - "type": "number" - } - } - }, - "codersdk.WorkspaceDeploymentStats": { - "type": "object", - "properties": { - "building": { - "type": "integer" - }, - "connection_latency_ms": { - "$ref": "#/definitions/codersdk.WorkspaceConnectionLatencyMS" - }, - "failed": { - "type": "integer" - }, - "pending": { - "type": "integer" - }, - "running": { - "type": "integer" - }, - "rx_bytes": { - "type": "integer" - }, - "stopped": { - "type": "integer" - }, - "tx_bytes": { - "type": "integer" - } - } - }, - "codersdk.WorkspaceHealth": { - "type": "object", - "properties": { - "failing_agents": { - "description": "FailingAgents lists the IDs of the agents that are failing, if any.", - "type": "array", - "items": { - "type": "string", - "format": "uuid" - } - }, - "healthy": { - "description": "Healthy is true if the workspace is healthy.", - "type": "boolean", - "example": false - } - } - }, - "codersdk.WorkspaceProxy": { - "type": "object", - "properties": { - "created_at": { - "type": "string", - "format": "date-time" - }, - "deleted": { - "type": "boolean" - }, - "derp_enabled": { - "type": "boolean" - }, - "derp_only": { - "type": "boolean" - }, - "display_name": { - "type": "string" - }, - "healthy": { - "type": "boolean" - }, - "icon_url": { - "type": "string" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "name": { - "type": "string" - }, - "path_app_url": { - "description": "PathAppURL is the URL to the base path for path apps. Optional\nunless wildcard_hostname is set.\nE.g. https://us.example.com", - "type": "string" - }, - "status": { - "description": "Status is the latest status check of the proxy. This will be empty for deleted\nproxies. This value can be used to determine if a workspace proxy is healthy\nand ready to use.", - "allOf": [ - { - "$ref": "#/definitions/codersdk.WorkspaceProxyStatus" - } - ] - }, - "updated_at": { - "type": "string", - "format": "date-time" - }, - "version": { - "type": "string" - }, - "wildcard_hostname": { - "description": "WildcardHostname is the wildcard hostname for subdomain apps.\nE.g. *.us.example.com\nE.g. *--suffix.au.example.com\nOptional. Does not need to be on the same domain as PathAppURL.", - "type": "string" - } - } - }, - "codersdk.WorkspaceProxyStatus": { - "type": "object", - "properties": { - "checked_at": { - "type": "string", - "format": "date-time" - }, - "report": { - "description": "Report provides more information about the health of the workspace proxy.", - "allOf": [ - { - "$ref": "#/definitions/codersdk.ProxyHealthReport" - } - ] - }, - "status": { - "$ref": "#/definitions/codersdk.ProxyHealthStatus" - } - } - }, - "codersdk.WorkspaceQuota": { - "type": "object", - "properties": { - "budget": { - "type": "integer" - }, - "credits_consumed": { - "type": "integer" - } - } - }, - "codersdk.WorkspaceResource": { - "type": "object", - "properties": { - "agents": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceAgent" - } - }, - "created_at": { - "type": "string", - "format": "date-time" - }, - "daily_cost": { - "type": "integer" - }, - "hide": { - "type": "boolean" - }, - "icon": { - "type": "string" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "job_id": { - "type": "string", - "format": "uuid" - }, - "metadata": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceResourceMetadata" - } - }, - "name": { - "type": "string" - }, - "type": { - "type": "string" - }, - "workspace_transition": { - "enum": ["start", "stop", "delete"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.WorkspaceTransition" - } - ] - } - } - }, - "codersdk.WorkspaceResourceMetadata": { - "type": "object", - "properties": { - "key": { - "type": "string" - }, - "sensitive": { - "type": "boolean" - }, - "value": { - "type": "string" - } - } - }, - "codersdk.WorkspaceStatus": { - "type": "string", - "enum": [ - "pending", - "starting", - "running", - "stopping", - "stopped", - "failed", - "canceling", - "canceled", - "deleting", - "deleted" - ], - "x-enum-varnames": [ - "WorkspaceStatusPending", - "WorkspaceStatusStarting", - "WorkspaceStatusRunning", - "WorkspaceStatusStopping", - "WorkspaceStatusStopped", - "WorkspaceStatusFailed", - "WorkspaceStatusCanceling", - "WorkspaceStatusCanceled", - "WorkspaceStatusDeleting", - "WorkspaceStatusDeleted" - ] - }, - "codersdk.WorkspaceTransition": { - "type": "string", - "enum": ["start", "stop", "delete"], - "x-enum-varnames": [ - "WorkspaceTransitionStart", - "WorkspaceTransitionStop", - "WorkspaceTransitionDelete" - ] - }, - "codersdk.WorkspacesResponse": { - "type": "object", - "properties": { - "count": { - "type": "integer" - }, - "workspaces": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Workspace" - } - } - } - }, - "derp.BytesSentRecv": { - "type": "object", - "properties": { - "key": { - "description": "Key is the public key of the client which sent/received these bytes.", - "allOf": [ - { - "$ref": "#/definitions/key.NodePublic" - } - ] - }, - "recv": { - "type": "integer" - }, - "sent": { - "type": "integer" - } - } - }, - "derp.ServerInfoMessage": { - "type": "object", - "properties": { - "tokenBucketBytesBurst": { - "description": "TokenBucketBytesBurst is how many bytes the server will\nallow to burst, temporarily violating\nTokenBucketBytesPerSecond.\n\nZero means unspecified. There might be a limit, but the\nclient need not try to respect it.", - "type": "integer" - }, - "tokenBucketBytesPerSecond": { - "description": "TokenBucketBytesPerSecond is how many bytes per second the\nserver says it will accept, including all framing bytes.\n\nZero means unspecified. There might be a limit, but the\nclient need not try to respect it.", - "type": "integer" - } - } - }, - "health.Code": { - "type": "string", - "enum": [ - "EUNKNOWN", - "EWP01", - "EWP02", - "EWP04", - "EDB01", - "EDB02", - "EWS01", - "EWS02", - "EWS03", - "EACS01", - "EACS02", - "EACS03", - "EACS04", - "EDERP01", - "EDERP02", - "EPD01", - "EPD02", - "EPD03" - ], - "x-enum-varnames": [ - "CodeUnknown", - "CodeProxyUpdate", - "CodeProxyFetch", - "CodeProxyUnhealthy", - "CodeDatabasePingFailed", - "CodeDatabasePingSlow", - "CodeWebsocketDial", - "CodeWebsocketEcho", - "CodeWebsocketMsg", - "CodeAccessURLNotSet", - "CodeAccessURLInvalid", - "CodeAccessURLFetch", - "CodeAccessURLNotOK", - "CodeDERPNodeUsesWebsocket", - "CodeDERPOneNodeUnhealthy", - "CodeProvisionerDaemonsNoProvisionerDaemons", - "CodeProvisionerDaemonVersionMismatch", - "CodeProvisionerDaemonAPIMajorVersionDeprecated" - ] - }, - "health.Message": { - "type": "object", - "properties": { - "code": { - "$ref": "#/definitions/health.Code" - }, - "message": { - "type": "string" - } - } - }, - "health.Severity": { - "type": "string", - "enum": ["ok", "warning", "error"], - "x-enum-varnames": ["SeverityOK", "SeverityWarning", "SeverityError"] - }, - "healthsdk.AccessURLReport": { - "type": "object", - "properties": { - "access_url": { - "type": "string" - }, - "dismissed": { - "type": "boolean" - }, - "error": { - "type": "string" - }, - "healthy": { - "description": "Healthy is deprecated and left for backward compatibility purposes, use `Severity` instead.", - "type": "boolean" - }, - "healthz_response": { - "type": "string" - }, - "reachable": { - "type": "boolean" - }, - "severity": { - "enum": ["ok", "warning", "error"], - "allOf": [ - { - "$ref": "#/definitions/health.Severity" - } - ] - }, - "status_code": { - "type": "integer" - }, - "warnings": { - "type": "array", - "items": { - "$ref": "#/definitions/health.Message" - } - } - } - }, - "healthsdk.DERPHealthReport": { - "type": "object", - "properties": { - "dismissed": { - "type": "boolean" - }, - "error": { - "type": "string" - }, - "healthy": { - "description": "Healthy is deprecated and left for backward compatibility purposes, use `Severity` instead.", - "type": "boolean" - }, - "netcheck": { - "$ref": "#/definitions/netcheck.Report" - }, - "netcheck_err": { - "type": "string" - }, - "netcheck_logs": { - "type": "array", - "items": { - "type": "string" - } - }, - "regions": { - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/healthsdk.DERPRegionReport" - } - }, - "severity": { - "enum": ["ok", "warning", "error"], - "allOf": [ - { - "$ref": "#/definitions/health.Severity" - } - ] - }, - "warnings": { - "type": "array", - "items": { - "$ref": "#/definitions/health.Message" - } - } - } - }, - "healthsdk.DERPNodeReport": { - "type": "object", - "properties": { - "can_exchange_messages": { - "type": "boolean" - }, - "client_errs": { - "type": "array", - "items": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "client_logs": { - "type": "array", - "items": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "error": { - "type": "string" - }, - "healthy": { - "description": "Healthy is deprecated and left for backward compatibility purposes, use `Severity` instead.", - "type": "boolean" - }, - "node": { - "$ref": "#/definitions/tailcfg.DERPNode" - }, - "node_info": { - "$ref": "#/definitions/derp.ServerInfoMessage" - }, - "round_trip_ping": { - "type": "string" - }, - "round_trip_ping_ms": { - "type": "integer" - }, - "severity": { - "enum": ["ok", "warning", "error"], - "allOf": [ - { - "$ref": "#/definitions/health.Severity" - } - ] - }, - "stun": { - "$ref": "#/definitions/healthsdk.STUNReport" - }, - "uses_websocket": { - "type": "boolean" - }, - "warnings": { - "type": "array", - "items": { - "$ref": "#/definitions/health.Message" - } - } - } - }, - "healthsdk.DERPRegionReport": { - "type": "object", - "properties": { - "error": { - "type": "string" - }, - "healthy": { - "description": "Healthy is deprecated and left for backward compatibility purposes, use `Severity` instead.", - "type": "boolean" - }, - "node_reports": { - "type": "array", - "items": { - "$ref": "#/definitions/healthsdk.DERPNodeReport" - } - }, - "region": { - "$ref": "#/definitions/tailcfg.DERPRegion" - }, - "severity": { - "enum": ["ok", "warning", "error"], - "allOf": [ - { - "$ref": "#/definitions/health.Severity" - } - ] - }, - "warnings": { - "type": "array", - "items": { - "$ref": "#/definitions/health.Message" - } - } - } - }, - "healthsdk.DatabaseReport": { - "type": "object", - "properties": { - "dismissed": { - "type": "boolean" - }, - "error": { - "type": "string" - }, - "healthy": { - "description": "Healthy is deprecated and left for backward compatibility purposes, use `Severity` instead.", - "type": "boolean" - }, - "latency": { - "type": "string" - }, - "latency_ms": { - "type": "integer" - }, - "reachable": { - "type": "boolean" - }, - "severity": { - "enum": ["ok", "warning", "error"], - "allOf": [ - { - "$ref": "#/definitions/health.Severity" - } - ] - }, - "threshold_ms": { - "type": "integer" - }, - "warnings": { - "type": "array", - "items": { - "$ref": "#/definitions/health.Message" - } - } - } - }, - "healthsdk.HealthSection": { - "type": "string", - "enum": [ - "DERP", - "AccessURL", - "Websocket", - "Database", - "WorkspaceProxy", - "ProvisionerDaemons" - ], - "x-enum-varnames": [ - "HealthSectionDERP", - "HealthSectionAccessURL", - "HealthSectionWebsocket", - "HealthSectionDatabase", - "HealthSectionWorkspaceProxy", - "HealthSectionProvisionerDaemons" - ] - }, - "healthsdk.HealthSettings": { - "type": "object", - "properties": { - "dismissed_healthchecks": { - "type": "array", - "items": { - "$ref": "#/definitions/healthsdk.HealthSection" - } - } - } - }, - "healthsdk.HealthcheckReport": { - "type": "object", - "properties": { - "access_url": { - "$ref": "#/definitions/healthsdk.AccessURLReport" - }, - "coder_version": { - "description": "The Coder version of the server that the report was generated on.", - "type": "string" - }, - "database": { - "$ref": "#/definitions/healthsdk.DatabaseReport" - }, - "derp": { - "$ref": "#/definitions/healthsdk.DERPHealthReport" - }, - "healthy": { - "description": "Healthy is true if the report returns no errors.\nDeprecated: use `Severity` instead", - "type": "boolean" - }, - "provisioner_daemons": { - "$ref": "#/definitions/healthsdk.ProvisionerDaemonsReport" - }, - "severity": { - "description": "Severity indicates the status of Coder health.", - "enum": ["ok", "warning", "error"], - "allOf": [ - { - "$ref": "#/definitions/health.Severity" - } - ] - }, - "time": { - "description": "Time is the time the report was generated at.", - "type": "string", - "format": "date-time" - }, - "websocket": { - "$ref": "#/definitions/healthsdk.WebsocketReport" - }, - "workspace_proxy": { - "$ref": "#/definitions/healthsdk.WorkspaceProxyReport" - } - } - }, - "healthsdk.ProvisionerDaemonsReport": { - "type": "object", - "properties": { - "dismissed": { - "type": "boolean" - }, - "error": { - "type": "string" - }, - "items": { - "type": "array", - "items": { - "$ref": "#/definitions/healthsdk.ProvisionerDaemonsReportItem" - } - }, - "severity": { - "enum": ["ok", "warning", "error"], - "allOf": [ - { - "$ref": "#/definitions/health.Severity" - } - ] - }, - "warnings": { - "type": "array", - "items": { - "$ref": "#/definitions/health.Message" - } - } - } - }, - "healthsdk.ProvisionerDaemonsReportItem": { - "type": "object", - "properties": { - "provisioner_daemon": { - "$ref": "#/definitions/codersdk.ProvisionerDaemon" - }, - "warnings": { - "type": "array", - "items": { - "$ref": "#/definitions/health.Message" - } - } - } - }, - "healthsdk.STUNReport": { - "type": "object", - "properties": { - "canSTUN": { - "type": "boolean" - }, - "enabled": { - "type": "boolean" - }, - "error": { - "type": "string" - } - } - }, - "healthsdk.UpdateHealthSettings": { - "type": "object", - "properties": { - "dismissed_healthchecks": { - "type": "array", - "items": { - "$ref": "#/definitions/healthsdk.HealthSection" - } - } - } - }, - "healthsdk.WebsocketReport": { - "type": "object", - "properties": { - "body": { - "type": "string" - }, - "code": { - "type": "integer" - }, - "dismissed": { - "type": "boolean" - }, - "error": { - "type": "string" - }, - "healthy": { - "description": "Healthy is deprecated and left for backward compatibility purposes, use `Severity` instead.", - "type": "boolean" - }, - "severity": { - "enum": ["ok", "warning", "error"], - "allOf": [ - { - "$ref": "#/definitions/health.Severity" - } - ] - }, - "warnings": { - "type": "array", - "items": { - "$ref": "#/definitions/health.Message" - } - } - } - }, - "healthsdk.WorkspaceProxyReport": { - "type": "object", - "properties": { - "dismissed": { - "type": "boolean" - }, - "error": { - "type": "string" - }, - "healthy": { - "description": "Healthy is deprecated and left for backward compatibility purposes, use `Severity` instead.", - "type": "boolean" - }, - "severity": { - "enum": ["ok", "warning", "error"], - "allOf": [ - { - "$ref": "#/definitions/health.Severity" - } - ] - }, - "warnings": { - "type": "array", - "items": { - "$ref": "#/definitions/health.Message" - } - }, - "workspace_proxies": { - "$ref": "#/definitions/codersdk.RegionsResponse-codersdk_WorkspaceProxy" - } - } - }, - "key.NodePublic": { - "type": "object" - }, - "netcheck.Report": { - "type": "object", - "properties": { - "captivePortal": { - "description": "CaptivePortal is set when we think there's a captive portal that is\nintercepting HTTP traffic.", - "type": "string" - }, - "globalV4": { - "description": "ip:port of global IPv4", - "type": "string" - }, - "globalV6": { - "description": "[ip]:port of global IPv6", - "type": "string" - }, - "hairPinning": { - "description": "HairPinning is whether the router supports communicating\nbetween two local devices through the NATted public IP address\n(on IPv4).", - "type": "string" - }, - "icmpv4": { - "description": "an ICMPv4 round trip completed", - "type": "boolean" - }, - "ipv4": { - "description": "an IPv4 STUN round trip completed", - "type": "boolean" - }, - "ipv4CanSend": { - "description": "an IPv4 packet was able to be sent", - "type": "boolean" - }, - "ipv6": { - "description": "an IPv6 STUN round trip completed", - "type": "boolean" - }, - "ipv6CanSend": { - "description": "an IPv6 packet was able to be sent", - "type": "boolean" - }, - "mappingVariesByDestIP": { - "description": "MappingVariesByDestIP is whether STUN results depend which\nSTUN server you're talking to (on IPv4).", - "type": "string" - }, - "oshasIPv6": { - "description": "could bind a socket to ::1", - "type": "boolean" - }, - "pcp": { - "description": "PCP is whether PCP appears present on the LAN.\nEmpty means not checked.", - "type": "string" - }, - "pmp": { - "description": "PMP is whether NAT-PMP appears present on the LAN.\nEmpty means not checked.", - "type": "string" - }, - "preferredDERP": { - "description": "or 0 for unknown", - "type": "integer" - }, - "regionLatency": { - "description": "keyed by DERP Region ID", - "type": "object", - "additionalProperties": { - "type": "integer" - } - }, - "regionV4Latency": { - "description": "keyed by DERP Region ID", - "type": "object", - "additionalProperties": { - "type": "integer" - } - }, - "regionV6Latency": { - "description": "keyed by DERP Region ID", - "type": "object", - "additionalProperties": { - "type": "integer" - } - }, - "udp": { - "description": "a UDP STUN round trip completed", - "type": "boolean" - }, - "upnP": { - "description": "UPnP is whether UPnP appears present on the LAN.\nEmpty means not checked.", - "type": "string" - } - } - }, - "oauth2.Token": { - "type": "object", - "properties": { - "access_token": { - "description": "AccessToken is the token that authorizes and authenticates\nthe requests.", - "type": "string" - }, - "expiry": { - "description": "Expiry is the optional expiration time of the access token.\n\nIf zero, TokenSource implementations will reuse the same\ntoken forever and RefreshToken or equivalent\nmechanisms for that TokenSource will not be used.", - "type": "string" - }, - "refresh_token": { - "description": "RefreshToken is a token that's used by the application\n(as opposed to the user) to refresh the access token\nif it expires.", - "type": "string" - }, - "token_type": { - "description": "TokenType is the type of token.\nThe Type method returns either this or \"Bearer\", the default.", - "type": "string" - } - } - }, - "serpent.Annotations": { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "serpent.Group": { - "type": "object", - "properties": { - "description": { - "type": "string" - }, - "name": { - "type": "string" - }, - "parent": { - "$ref": "#/definitions/serpent.Group" - }, - "yaml": { - "type": "string" - } - } - }, - "serpent.HostPort": { - "type": "object", - "properties": { - "host": { - "type": "string" - }, - "port": { - "type": "string" - } - } - }, - "serpent.Option": { - "type": "object", - "properties": { - "annotations": { - "description": "Annotations enable extensions to serpent higher up in the stack. It's useful for\nhelp formatting and documentation generation.", - "allOf": [ - { - "$ref": "#/definitions/serpent.Annotations" - } - ] - }, - "default": { - "description": "Default is parsed into Value if set.", - "type": "string" - }, - "description": { - "type": "string" - }, - "env": { - "description": "Env is the environment variable used to configure this option. If unset,\nenvironment configuring is disabled.", - "type": "string" - }, - "flag": { - "description": "Flag is the long name of the flag used to configure this option. If unset,\nflag configuring is disabled.", - "type": "string" - }, - "flag_shorthand": { - "description": "FlagShorthand is the one-character shorthand for the flag. If unset, no\nshorthand is used.", - "type": "string" - }, - "group": { - "description": "Group is a group hierarchy that helps organize this option in help, configs\nand other documentation.", - "allOf": [ - { - "$ref": "#/definitions/serpent.Group" - } - ] - }, - "hidden": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "required": { - "description": "Required means this value must be set by some means. It requires\n`ValueSource != ValueSourceNone`\nIf `Default` is set, then `Required` is ignored.", - "type": "boolean" - }, - "use_instead": { - "description": "UseInstead is a list of options that should be used instead of this one.\nThe field is used to generate a deprecation warning.", - "type": "array", - "items": { - "$ref": "#/definitions/serpent.Option" - } - }, - "value": { - "description": "Value includes the types listed in values.go." - }, - "value_source": { - "$ref": "#/definitions/serpent.ValueSource" - }, - "yaml": { - "description": "YAML is the YAML key used to configure this option. If unset, YAML\nconfiguring is disabled.", - "type": "string" - } - } - }, - "serpent.Regexp": { - "type": "object" - }, - "serpent.Struct-array_codersdk_ExternalAuthConfig": { - "type": "object", - "properties": { - "value": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.ExternalAuthConfig" - } - } - } - }, - "serpent.Struct-array_codersdk_LinkConfig": { - "type": "object", - "properties": { - "value": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.LinkConfig" - } - } - } - }, - "serpent.URL": { - "type": "object", - "properties": { - "forceQuery": { - "description": "append a query ('?') even if RawQuery is empty", - "type": "boolean" - }, - "fragment": { - "description": "fragment for references, without '#'", - "type": "string" - }, - "host": { - "description": "host or host:port (see Hostname and Port methods)", - "type": "string" - }, - "omitHost": { - "description": "do not emit empty host (authority)", - "type": "boolean" - }, - "opaque": { - "description": "encoded opaque data", - "type": "string" - }, - "path": { - "description": "path (relative paths may omit leading slash)", - "type": "string" - }, - "rawFragment": { - "description": "encoded fragment hint (see EscapedFragment method)", - "type": "string" - }, - "rawPath": { - "description": "encoded path hint (see EscapedPath method)", - "type": "string" - }, - "rawQuery": { - "description": "encoded query values, without '?'", - "type": "string" - }, - "scheme": { - "type": "string" - }, - "user": { - "description": "username and password information", - "allOf": [ - { - "$ref": "#/definitions/url.Userinfo" - } - ] - } - } - }, - "serpent.ValueSource": { - "type": "string", - "enum": ["", "flag", "env", "yaml", "default"], - "x-enum-varnames": [ - "ValueSourceNone", - "ValueSourceFlag", - "ValueSourceEnv", - "ValueSourceYAML", - "ValueSourceDefault" - ] - }, - "tailcfg.DERPHomeParams": { - "type": "object", - "properties": { - "regionScore": { - "description": "RegionScore scales latencies of DERP regions by a given scaling\nfactor when determining which region to use as the home\n(\"preferred\") DERP. Scores in the range (0, 1) will cause this\nregion to be proportionally more preferred, and scores in the range\n(1, ∞) will penalize a region.\n\nIf a region is not present in this map, it is treated as having a\nscore of 1.0.\n\nScores should not be 0 or negative; such scores will be ignored.\n\nA nil map means no change from the previous value (if any); an empty\nnon-nil map can be sent to reset all scores back to 1.0.", - "type": "object", - "additionalProperties": { - "type": "number" - } - } - } - }, - "tailcfg.DERPMap": { - "type": "object", - "properties": { - "homeParams": { - "description": "HomeParams, if non-nil, is a change in home parameters.\n\nThe rest of the DEPRMap fields, if zero, means unchanged.", - "allOf": [ - { - "$ref": "#/definitions/tailcfg.DERPHomeParams" - } - ] - }, - "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.\n\nThis field is only meaningful if the Regions map is non-nil (indicating a change).", - "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": { - "canPort80": { - "description": "CanPort80 specifies whether this DERP node is accessible over HTTP\non port 80 specifically. This is used for captive portal checks.", - "type": "boolean" - }, - "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" - } - } - }, - "url.Userinfo": { - "type": "object" - }, - "workspaceapps.AccessMethod": { - "type": "string", - "enum": ["path", "subdomain", "terminal"], - "x-enum-varnames": [ - "AccessMethodPath", - "AccessMethodSubdomain", - "AccessMethodTerminal" - ] - }, - "workspaceapps.IssueTokenRequest": { - "type": "object", - "properties": { - "app_hostname": { - "description": "AppHostname is the optional hostname for subdomain apps on the external\nproxy. It must start with an asterisk.", - "type": "string" - }, - "app_path": { - "description": "AppPath is the path of the user underneath the app base path.", - "type": "string" - }, - "app_query": { - "description": "AppQuery is the query parameters the user provided in the app request.", - "type": "string" - }, - "app_request": { - "$ref": "#/definitions/workspaceapps.Request" - }, - "path_app_base_url": { - "description": "PathAppBaseURL is required.", - "type": "string" - }, - "session_token": { - "description": "SessionToken is the session token provided by the user.", - "type": "string" - } - } - }, - "workspaceapps.Request": { - "type": "object", - "properties": { - "access_method": { - "$ref": "#/definitions/workspaceapps.AccessMethod" - }, - "agent_name_or_id": { - "description": "AgentNameOrID is not required if the workspace has only one agent.", - "type": "string" - }, - "app_prefix": { - "description": "Prefix is the prefix of the subdomain app URL. Prefix should have a\ntrailing \"---\" if set.", - "type": "string" - }, - "app_slug_or_port": { - "type": "string" - }, - "base_path": { - "description": "BasePath of the app. For path apps, this is the path prefix in the router\nfor this particular app. For subdomain apps, this should be \"/\". This is\nused for setting the cookie path.", - "type": "string" - }, - "username_or_id": { - "description": "For the following fields, if the AccessMethod is AccessMethodTerminal,\nthen only AgentNameOrID may be set and it must be a UUID. The other\nfields must be left blank.", - "type": "string" - }, - "workspace_name_or_id": { - "type": "string" - } - } - }, - "workspaceapps.StatsReport": { - "type": "object", - "properties": { - "access_method": { - "$ref": "#/definitions/workspaceapps.AccessMethod" - }, - "agent_id": { - "type": "string" - }, - "requests": { - "type": "integer" - }, - "session_ended_at": { - "description": "Updated periodically while app is in use active and when the last connection is closed.", - "type": "string" - }, - "session_id": { - "type": "string" - }, - "session_started_at": { - "type": "string" - }, - "slug_or_port": { - "type": "string" - }, - "user_id": { - "type": "string" - }, - "workspace_id": { - "type": "string" - } - } - }, - "workspacesdk.AgentConnectionInfo": { - "type": "object", - "properties": { - "derp_force_websockets": { - "type": "boolean" - }, - "derp_map": { - "$ref": "#/definitions/tailcfg.DERPMap" - }, - "disable_direct_connections": { - "type": "boolean" - } - } - }, - "wsproxysdk.DeregisterWorkspaceProxyRequest": { - "type": "object", - "properties": { - "replica_id": { - "description": "ReplicaID is a unique identifier for the replica of the proxy that is\nderegistering. It should be generated by the client on startup and\nshould've already been passed to the register endpoint.", - "type": "string" - } - } - }, - "wsproxysdk.IssueSignedAppTokenResponse": { - "type": "object", - "properties": { - "signed_token_str": { - "description": "SignedTokenStr should be set as a cookie on the response.", - "type": "string" - } - } - }, - "wsproxysdk.RegisterWorkspaceProxyRequest": { - "type": "object", - "properties": { - "access_url": { - "description": "AccessURL that hits the workspace proxy api.", - "type": "string" - }, - "derp_enabled": { - "description": "DerpEnabled indicates whether the proxy should be included in the DERP\nmap or not.", - "type": "boolean" - }, - "derp_only": { - "description": "DerpOnly indicates whether the proxy should only be included in the DERP\nmap and should not be used for serving apps.", - "type": "boolean" - }, - "hostname": { - "description": "ReplicaHostname is the OS hostname of the machine that the proxy is running\non. This is only used for tracking purposes in the replicas table.", - "type": "string" - }, - "replica_error": { - "description": "ReplicaError is the error that the replica encountered when trying to\ndial it's peers. This is stored in the replicas table for debugging\npurposes but does not affect the proxy's ability to register.\n\nThis value is only stored on subsequent requests to the register\nendpoint, not the first request.", - "type": "string" - }, - "replica_id": { - "description": "ReplicaID is a unique identifier for the replica of the proxy that is\nregistering. It should be generated by the client on startup and\npersisted (in memory only) until the process is restarted.", - "type": "string" - }, - "replica_relay_address": { - "description": "ReplicaRelayAddress is the DERP address of the replica that other\nreplicas may use to connect internally for DERP meshing.", - "type": "string" - }, - "version": { - "description": "Version is the Coder version of the proxy.", - "type": "string" - }, - "wildcard_hostname": { - "description": "WildcardHostname that the workspace proxy api is serving for subdomain apps.", - "type": "string" - } - } - }, - "wsproxysdk.RegisterWorkspaceProxyResponse": { - "type": "object", - "properties": { - "app_security_key": { - "type": "string" - }, - "derp_force_websockets": { - "type": "boolean" - }, - "derp_map": { - "$ref": "#/definitions/tailcfg.DERPMap" - }, - "derp_mesh_key": { - "type": "string" - }, - "derp_region_id": { - "type": "integer" - }, - "sibling_replicas": { - "description": "SiblingReplicas is a list of all other replicas of the proxy that have\nnot timed out.", - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Replica" - } - } - } - }, - "wsproxysdk.ReportAppStatsRequest": { - "type": "object", - "properties": { - "stats": { - "type": "array", - "items": { - "$ref": "#/definitions/workspaceapps.StatsReport" - } - } - } - } - }, - "securityDefinitions": { - "CoderSessionToken": { - "type": "apiKey", - "name": "Coder-Session-Token", - "in": "header" - } - } + "swagger": "2.0", + "info": { + "description": "Coderd is the service created by running coder server. It is a thin API that connects workspaces, provisioners and users. coderd stores its state in Postgres and is the only service that communicates with Postgres.", + "title": "Coder API", + "termsOfService": "https://coder.com/legal/terms-of-service", + "contact": { + "name": "API Support", + "url": "https://coder.com", + "email": "support@coder.com" + }, + "license": { + "name": "AGPL-3.0", + "url": "https://github.com/coder/coder/blob/main/LICENSE" + }, + "version": "2.0" + }, + "basePath": "/api/v2", + "paths": { + "/": { + "get": { + "produces": ["application/json"], + "tags": ["General"], + "summary": "API root handler", + "operationId": "api-root-handler", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, + "/appearance": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Get appearance", + "operationId": "get-appearance", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.AppearanceConfig" + } + } + } + }, + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Update appearance", + "operationId": "update-appearance", + "parameters": [ + { + "description": "Update appearance request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateAppearanceConfig" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.UpdateAppearanceConfig" + } + } + } + } + }, + "/applications/auth-redirect": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": ["Applications"], + "summary": "Redirect to URI with encrypted API key", + "operationId": "redirect-to-uri-with-encrypted-api-key", + "parameters": [ + { + "type": "string", + "description": "Redirect destination", + "name": "redirect_uri", + "in": "query" + } + ], + "responses": { + "307": { + "description": "Temporary Redirect" + } + } + } + }, + "/applications/host": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Applications"], + "summary": "Get applications host", + "operationId": "get-applications-host", + "deprecated": true, + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.AppHostResponse" + } + } + } + } + }, + "/applications/reconnecting-pty-signed-token": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Issue signed app token for reconnecting PTY", + "operationId": "issue-signed-app-token-for-reconnecting-pty", + "parameters": [ + { + "description": "Issue reconnecting PTY signed token request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.IssueReconnectingPTYSignedTokenRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.IssueReconnectingPTYSignedTokenResponse" + } + } + }, + "x-apidocgen": { + "skip": true + } + } + }, + "/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" + }, + { + "type": "integer", + "description": "Page limit", + "name": "limit", + "in": "query", + "required": true + }, + { + "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-log", + "parameters": [ + { + "description": "Audit log request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateTestAuditLogRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + } + }, + "x-apidocgen": { + "skip": true + } + } + }, + "/authcheck": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Authorization"], + "summary": "Check authorization", + "operationId": "check-authorization", + "parameters": [ + { + "description": "Authorization request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.AuthorizationRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.AuthorizationResponse" + } + } + } + } + }, + "/buildinfo": { + "get": { + "produces": ["application/json"], + "tags": ["General"], + "summary": "Build info", + "operationId": "build-info", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.BuildInfoResponse" + } + } + } + } + }, + "/csp/reports": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "tags": ["General"], + "summary": "Report CSP violations", + "operationId": "report-csp-violations", + "parameters": [ + { + "description": "Violation report", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/coderd.cspViolation" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/debug/coordinator": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["text/html"], + "tags": ["Debug"], + "summary": "Debug Info Wireguard Coordinator", + "operationId": "debug-info-wireguard-coordinator", + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/debug/derp/traffic": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Debug"], + "summary": "Debug DERP traffic", + "operationId": "debug-derp-traffic", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/derp.BytesSentRecv" + } + } + } + }, + "x-apidocgen": { + "skip": true + } + } + }, + "/debug/expvar": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Debug"], + "summary": "Debug expvar", + "operationId": "debug-expvar", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + } + }, + "x-apidocgen": { + "skip": true + } + } + }, + "/debug/health": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Debug"], + "summary": "Debug Info Deployment Health", + "operationId": "debug-info-deployment-health", + "parameters": [ + { + "type": "boolean", + "description": "Force a healthcheck to run", + "name": "force", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/healthsdk.HealthcheckReport" + } + } + } + } + }, + "/debug/health/settings": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Debug"], + "summary": "Get health settings", + "operationId": "get-health-settings", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/healthsdk.HealthSettings" + } + } + } + }, + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Debug"], + "summary": "Update health settings", + "operationId": "update-health-settings", + "parameters": [ + { + "description": "Update health settings", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/healthsdk.UpdateHealthSettings" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/healthsdk.UpdateHealthSettings" + } + } + } + } + }, + "/debug/tailnet": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["text/html"], + "tags": ["Debug"], + "summary": "Debug Info Tailnet", + "operationId": "debug-info-tailnet", + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/debug/ws": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Debug"], + "summary": "Debug Info Websocket Test", + "operationId": "debug-info-websocket-test", + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + }, + "x-apidocgen": { + "skip": true + } + } + }, + "/debug/{user}/debug-link": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": ["Agents"], + "summary": "Debug OIDC context for a user", + "operationId": "debug-oidc-context-for-a-user", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Success" + } + }, + "x-apidocgen": { + "skip": true + } + } + }, + "/deployment/config": { + "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" + } + } + } + } + }, + "/deployment/ssh": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["General"], + "summary": "SSH Config", + "operationId": "ssh-config", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.SSHConfigResponse" + } + } + } + } + }, + "/deployment/stats": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["General"], + "summary": "Get deployment stats", + "operationId": "get-deployment-stats", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.DeploymentStats" + } + } + } + } + }, + "/derp-map": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": ["Agents"], + "summary": "Get DERP map updates", + "operationId": "get-derp-map-updates", + "responses": { + "101": { + "description": "Switching Protocols" + } + } + } + }, + "/entitlements": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Get entitlements", + "operationId": "get-entitlements", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Entitlements" + } + } + } + } + }, + "/experiments": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["General"], + "summary": "Get enabled experiments", + "operationId": "get-enabled-experiments", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Experiment" + } + } + } + } + } + }, + "/experiments/available": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["General"], + "summary": "Get safe experiments", + "operationId": "get-safe-experiments", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Experiment" + } + } + } + } + } + }, + "/external-auth": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Git"], + "summary": "Get user external auths", + "operationId": "get-user-external-auths", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.ExternalAuthLink" + } + } + } + } + }, + "/external-auth/{externalauth}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Git"], + "summary": "Get external auth by ID", + "operationId": "get-external-auth-by-id", + "parameters": [ + { + "type": "string", + "format": "string", + "description": "Git Provider ID", + "name": "externalauth", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.ExternalAuth" + } + } + } + }, + "delete": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": ["Git"], + "summary": "Delete external auth user link by ID", + "operationId": "delete-external-auth-user-link-by-id", + "parameters": [ + { + "type": "string", + "format": "string", + "description": "Git Provider ID", + "name": "externalauth", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/external-auth/{externalauth}/device": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Git"], + "summary": "Get external auth device by ID.", + "operationId": "get-external-auth-device-by-id", + "parameters": [ + { + "type": "string", + "format": "string", + "description": "Git Provider ID", + "name": "externalauth", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.ExternalAuthDevice" + } + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": ["Git"], + "summary": "Post external auth device by ID", + "operationId": "post-external-auth-device-by-id", + "parameters": [ + { + "type": "string", + "format": "string", + "description": "External Provider ID", + "name": "externalauth", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/files": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "description": "Swagger 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": "upload-file", + "parameters": [ + { + "type": "string", + "default": "application/x-tar", + "description": "Content-Type must be `application/x-tar` or `application/zip`", + "name": "Content-Type", + "in": "header", + "required": true + }, + { + "type": "file", + "description": "File to be uploaded. If using tar format, file must conform to ustar (pax may cause problems).", + "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" + } + } + } + }, + "/groups": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Get groups", + "operationId": "get-groups", + "parameters": [ + { + "type": "string", + "description": "Organization ID or name", + "name": "organization", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "User ID or name", + "name": "has_member", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Group" + } + } + } + } + } + }, + "/groups/{group}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Get group by ID", + "operationId": "get-group-by-id", + "parameters": [ + { + "type": "string", + "description": "Group id", + "name": "group", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Group" + } + } + } + }, + "delete": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Delete group by name", + "operationId": "delete-group-by-name", + "parameters": [ + { + "type": "string", + "description": "Group name", + "name": "group", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Group" + } + } + } + }, + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Update group by name", + "operationId": "update-group-by-name", + "parameters": [ + { + "type": "string", + "description": "Group name", + "name": "group", + "in": "path", + "required": true + }, + { + "description": "Patch group request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.PatchGroupRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Group" + } + } + } + } + }, + "/insights/daus": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Insights"], + "summary": "Get deployment DAUs", + "operationId": "get-deployment-daus", + "parameters": [ + { + "type": "integer", + "description": "Time-zone offset (e.g. -2)", + "name": "tz_offset", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.DAUsResponse" + } + } + } + } + }, + "/insights/templates": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Insights"], + "summary": "Get insights about templates", + "operationId": "get-insights-about-templates", + "parameters": [ + { + "type": "string", + "format": "date-time", + "description": "Start time", + "name": "start_time", + "in": "query", + "required": true + }, + { + "type": "string", + "format": "date-time", + "description": "End time", + "name": "end_time", + "in": "query", + "required": true + }, + { + "enum": ["week", "day"], + "type": "string", + "description": "Interval", + "name": "interval", + "in": "query", + "required": true + }, + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "csv", + "description": "Template IDs", + "name": "template_ids", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.TemplateInsightsResponse" + } + } + } + } + }, + "/insights/user-activity": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Insights"], + "summary": "Get insights about user activity", + "operationId": "get-insights-about-user-activity", + "parameters": [ + { + "type": "string", + "format": "date-time", + "description": "Start time", + "name": "start_time", + "in": "query", + "required": true + }, + { + "type": "string", + "format": "date-time", + "description": "End time", + "name": "end_time", + "in": "query", + "required": true + }, + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "csv", + "description": "Template IDs", + "name": "template_ids", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.UserActivityInsightsResponse" + } + } + } + } + }, + "/insights/user-latency": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Insights"], + "summary": "Get insights about user latency", + "operationId": "get-insights-about-user-latency", + "parameters": [ + { + "type": "string", + "format": "date-time", + "description": "Start time", + "name": "start_time", + "in": "query", + "required": true + }, + { + "type": "string", + "format": "date-time", + "description": "End time", + "name": "end_time", + "in": "query", + "required": true + }, + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "csv", + "description": "Template IDs", + "name": "template_ids", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.UserLatencyInsightsResponse" + } + } + } + } + }, + "/integrations/jfrog/xray-scan": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Get JFrog XRay scan by workspace agent ID.", + "operationId": "get-jfrog-xray-scan-by-workspace-agent-id", + "parameters": [ + { + "type": "string", + "description": "Workspace ID", + "name": "workspace_id", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "Agent ID", + "name": "agent_id", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.JFrogXrayScan" + } + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Post JFrog XRay scan by workspace agent ID.", + "operationId": "post-jfrog-xray-scan-by-workspace-agent-id", + "parameters": [ + { + "description": "Post JFrog XRay scan request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.JFrogXrayScan" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, + "/licenses": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Get licenses", + "operationId": "get-licenses", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.License" + } + } + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Organizations"], + "summary": "Add new license", + "operationId": "add-new-license", + "parameters": [ + { + "description": "Add license request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.AddLicenseRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.License" + } + } + } + } + }, + "/licenses/refresh-entitlements": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Organizations"], + "summary": "Update license entitlements", + "operationId": "update-license-entitlements", + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, + "/licenses/{id}": { + "delete": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Delete license", + "operationId": "delete-license", + "parameters": [ + { + "type": "string", + "format": "number", + "description": "License ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/notifications/dispatch-methods": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Notifications"], + "summary": "Get notification dispatch methods", + "operationId": "get-notification-dispatch-methods", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.NotificationMethodsResponse" + } + } + } + } + } + }, + "/notifications/settings": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Notifications"], + "summary": "Get notifications settings", + "operationId": "get-notifications-settings", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.NotificationsSettings" + } + } + } + }, + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Notifications"], + "summary": "Update notifications settings", + "operationId": "update-notifications-settings", + "parameters": [ + { + "description": "Notifications settings request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.NotificationsSettings" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.NotificationsSettings" + } + }, + "304": { + "description": "Not Modified" + } + } + } + }, + "/notifications/templates/system": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Notifications"], + "summary": "Get system notification templates", + "operationId": "get-system-notification-templates", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.NotificationTemplate" + } + } + } + } + } + }, + "/notifications/templates/{notification_template}/method": { + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Update notification template dispatch method", + "operationId": "update-notification-template-dispatch-method", + "parameters": [ + { + "type": "string", + "description": "Notification template UUID", + "name": "notification_template", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Success" + }, + "304": { + "description": "Not modified" + } + } + } + }, + "/oauth2-provider/apps": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Get OAuth2 applications.", + "operationId": "get-oauth2-applications", + "parameters": [ + { + "type": "string", + "description": "Filter by applications authorized for a user", + "name": "user_id", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.OAuth2ProviderApp" + } + } + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Create OAuth2 application.", + "operationId": "create-oauth2-application", + "parameters": [ + { + "description": "The OAuth2 application to create.", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.PostOAuth2ProviderAppRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.OAuth2ProviderApp" + } + } + } + } + }, + "/oauth2-provider/apps/{app}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Get OAuth2 application.", + "operationId": "get-oauth2-application", + "parameters": [ + { + "type": "string", + "description": "App ID", + "name": "app", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.OAuth2ProviderApp" + } + } + } + }, + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Update OAuth2 application.", + "operationId": "update-oauth2-application", + "parameters": [ + { + "type": "string", + "description": "App ID", + "name": "app", + "in": "path", + "required": true + }, + { + "description": "Update an OAuth2 application.", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.PutOAuth2ProviderAppRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.OAuth2ProviderApp" + } + } + } + }, + "delete": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": ["Enterprise"], + "summary": "Delete OAuth2 application.", + "operationId": "delete-oauth2-application", + "parameters": [ + { + "type": "string", + "description": "App ID", + "name": "app", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/oauth2-provider/apps/{app}/secrets": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Get OAuth2 application secrets.", + "operationId": "get-oauth2-application-secrets", + "parameters": [ + { + "type": "string", + "description": "App ID", + "name": "app", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.OAuth2ProviderAppSecret" + } + } + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Create OAuth2 application secret.", + "operationId": "create-oauth2-application-secret", + "parameters": [ + { + "type": "string", + "description": "App ID", + "name": "app", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.OAuth2ProviderAppSecretFull" + } + } + } + } + } + }, + "/oauth2-provider/apps/{app}/secrets/{secretID}": { + "delete": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": ["Enterprise"], + "summary": "Delete OAuth2 application secret.", + "operationId": "delete-oauth2-application-secret", + "parameters": [ + { + "type": "string", + "description": "App ID", + "name": "app", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Secret ID", + "name": "secretID", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/oauth2/authorize": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": ["Enterprise"], + "summary": "OAuth2 authorization request.", + "operationId": "oauth2-authorization-request", + "parameters": [ + { + "type": "string", + "description": "Client ID", + "name": "client_id", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "A random unguessable string", + "name": "state", + "in": "query", + "required": true + }, + { + "enum": ["code"], + "type": "string", + "description": "Response type", + "name": "response_type", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "Redirect here after authorization", + "name": "redirect_uri", + "in": "query" + }, + { + "type": "string", + "description": "Token scopes (currently ignored)", + "name": "scope", + "in": "query" + } + ], + "responses": { + "302": { + "description": "Found" + } + } + } + }, + "/oauth2/tokens": { + "post": { + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "OAuth2 token exchange.", + "operationId": "oauth2-token-exchange", + "parameters": [ + { + "type": "string", + "description": "Client ID, required if grant_type=authorization_code", + "name": "client_id", + "in": "formData" + }, + { + "type": "string", + "description": "Client secret, required if grant_type=authorization_code", + "name": "client_secret", + "in": "formData" + }, + { + "type": "string", + "description": "Authorization code, required if grant_type=authorization_code", + "name": "code", + "in": "formData" + }, + { + "type": "string", + "description": "Refresh token, required if grant_type=refresh_token", + "name": "refresh_token", + "in": "formData" + }, + { + "enum": ["authorization_code", "refresh_token"], + "type": "string", + "description": "Grant type", + "name": "grant_type", + "in": "formData", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/oauth2.Token" + } + } + } + }, + "delete": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": ["Enterprise"], + "summary": "Delete OAuth2 application tokens.", + "operationId": "delete-oauth2-application-tokens", + "parameters": [ + { + "type": "string", + "description": "Client ID", + "name": "client_id", + "in": "query", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/organizations": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Organizations"], + "summary": "Get organizations", + "operationId": "get-organizations", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Organization" + } + } + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "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/{organization}": { + "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": "organization", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Organization" + } + } + } + }, + "delete": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Organizations"], + "summary": "Delete organization", + "operationId": "delete-organization", + "parameters": [ + { + "type": "string", + "description": "Organization ID or name", + "name": "organization", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + }, + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Organizations"], + "summary": "Update organization", + "operationId": "update-organization", + "parameters": [ + { + "type": "string", + "description": "Organization ID or name", + "name": "organization", + "in": "path", + "required": true + }, + { + "description": "Patch organization request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateOrganizationRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Organization" + } + } + } + } + }, + "/organizations/{organization}/groups": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Get groups by organization", + "operationId": "get-groups-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.Group" + } + } + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Create group for organization", + "operationId": "create-group-for-organization", + "parameters": [ + { + "description": "Create group request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateGroupRequest" + } + }, + { + "type": "string", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.Group" + } + } + } + } + }, + "/organizations/{organization}/groups/{groupName}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Get group by organization and group name", + "operationId": "get-group-by-organization-and-group-name", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Group name", + "name": "groupName", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Group" + } + } + } + } + }, + "/organizations/{organization}/members": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Members"], + "summary": "List organization members", + "operationId": "list-organization-members", + "parameters": [ + { + "type": "string", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.OrganizationMemberWithUserData" + } + } + } + } + } + }, + "/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" + } + } + } + } + }, + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Members"], + "summary": "Upsert a custom organization role", + "operationId": "upsert-a-custom-organization-role", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + }, + { + "description": "Upsert role request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CustomRoleRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Role" + } + } + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Members"], + "summary": "Insert a custom organization role", + "operationId": "insert-a-custom-organization-role", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + }, + { + "description": "Insert role request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CustomRoleRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Role" + } + } + } + } + } + }, + "/organizations/{organization}/members/roles/{roleName}": { + "delete": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Members"], + "summary": "Delete a custom organization role", + "operationId": "delete-a-custom-organization-role", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Role name", + "name": "roleName", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Role" + } + } + } + } + } + }, + "/organizations/{organization}/members/{user}": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Members"], + "summary": "Add organization member", + "operationId": "add-organization-member", + "parameters": [ + { + "type": "string", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.OrganizationMember" + } + } + } + }, + "delete": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": ["Members"], + "summary": "Remove organization member", + "operationId": "remove-organization-member", + "parameters": [ + { + "type": "string", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/organizations/{organization}/members/{user}/roles": { + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Members"], + "summary": "Assign role to organization member", + "operationId": "assign-role-to-organization-member", + "parameters": [ + { + "type": "string", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + }, + { + "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.OrganizationMember" + } + } + } + } + }, + "/organizations/{organization}/members/{user}/workspaces": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "description": "Create a new workspace using a template. The request must\nspecify either the Template ID or the Template Version ID,\nnot both. If the Template ID is specified, the active version\nof the template will be used.", + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Workspaces"], + "summary": "Create user workspace by organization", + "operationId": "create-user-workspace-by-organization", + "deprecated": true, + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Username, UUID, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "description": "Create workspace request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateWorkspaceRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Workspace" + } + } + } + } + }, + "/organizations/{organization}/provisionerdaemons": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Get provisioner daemons", + "operationId": "get-provisioner-daemons", + "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.ProvisionerDaemon" + } + } + } + } + } + }, + "/organizations/{organization}/provisionerdaemons/serve": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": ["Enterprise"], + "summary": "Serve provisioner daemon", + "operationId": "serve-provisioner-daemon", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + } + ], + "responses": { + "101": { + "description": "Switching Protocols" + } + } + } + }, + "/organizations/{organization}/provisionerkeys": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "List provisioner key", + "operationId": "list-provisioner-key", + "parameters": [ + { + "type": "string", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.ProvisionerKey" + } + } + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Create provisioner key", + "operationId": "create-provisioner-key", + "parameters": [ + { + "type": "string", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.CreateProvisionerKeyResponse" + } + } + } + } + }, + "/organizations/{organization}/provisionerkeys/{provisionerkey}": { + "delete": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": ["Enterprise"], + "summary": "Delete provisioner key", + "operationId": "delete-provisioner-key", + "parameters": [ + { + "type": "string", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Provisioner key name", + "name": "provisionerkey", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/organizations/{organization}/templates": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get templates by organization", + "operationId": "get-templates-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.Template" + } + } + } + } + }, + "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", + "deprecated": true, + "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/{templatename}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get templates by organization and template name", + "operationId": "get-templates-by-organization-and-template-name", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Template name", + "name": "templatename", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Template" + } + } + } + } + }, + "/organizations/{organization}/templates/{templatename}/versions/{templateversionname}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get template version by organization, template, and name", + "operationId": "get-template-version-by-organization-template-and-name", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Template name", + "name": "templatename", + "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}/templates/{templatename}/versions/{templateversionname}/previous": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get previous template version by organization, template, and name", + "operationId": "get-previous-template-version-by-organization-template-and-name", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Template name", + "name": "templatename", + "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": { + "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.CreateTemplateVersionRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.TemplateVersion" + } + } + } + } + }, + "/regions": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["WorkspaceProxies"], + "summary": "Get site-wide regions for workspace connections", + "operationId": "get-site-wide-regions-for-workspace-connections", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.RegionsResponse-codersdk_Region" + } + } + } + } + }, + "/replicas": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Get active replicas", + "operationId": "get-active-replicas", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Replica" + } + } + } + } + } + }, + "/scim/v2/Users": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/scim+json"], + "tags": ["Enterprise"], + "summary": "SCIM 2.0: Get users", + "operationId": "scim-get-users", + "responses": { + "200": { + "description": "OK" + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "SCIM 2.0: Create new user", + "operationId": "scim-create-new-user", + "parameters": [ + { + "description": "New user", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/coderd.SCIMUser" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/coderd.SCIMUser" + } + } + } + } + }, + "/scim/v2/Users/{id}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/scim+json"], + "tags": ["Enterprise"], + "summary": "SCIM 2.0: Get user by ID", + "operationId": "scim-get-user-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "User ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "404": { + "description": "Not Found" + } + } + }, + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/scim+json"], + "tags": ["Enterprise"], + "summary": "SCIM 2.0: Update user account", + "operationId": "scim-update-user-status", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "User ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Update user request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/coderd.SCIMUser" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.User" + } + } + } + } + }, + "/templates": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get all templates", + "operationId": "get-all-templates", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Template" + } + } + } + } + } + }, + "/templates/examples": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get template examples", + "operationId": "get-template-examples", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.TemplateExample" + } + } + } + } + } + }, + "/templates/{template}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get template metadata by ID", + "operationId": "get-template-metadata-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "template", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Template" + } + } + } + }, + "delete": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Delete template by ID", + "operationId": "delete-template-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "template", + "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-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "template", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Template" + } + } + } + } + }, + "/templates/{template}/acl": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Get template ACLs", + "operationId": "get-template-acls", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "template", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.TemplateUser" + } + } + } + } + }, + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Update template ACL", + "operationId": "update-template-acl", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "template", + "in": "path", + "required": true + }, + { + "description": "Update template request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateTemplateACL" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, + "/templates/{template}/acl/available": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Get template available acl users/groups", + "operationId": "get-template-available-acl-usersgroups", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "template", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.ACLAvailable" + } + } + } + } + } + }, + "/templates/{template}/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": "template", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.DAUsResponse" + } + } + } + } + }, + "/templates/{template}/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": "template", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "After ID", + "name": "after_id", + "in": "query" + }, + { + "type": "boolean", + "description": "Include archived versions in the list", + "name": "include_archived", + "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": { + "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": "template", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, + "/templates/{template}/versions/archive": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Archive template unused versions by template id", + "operationId": "archive-template-unused-versions-by-template-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "template", + "in": "path", + "required": true + }, + { + "description": "Archive request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.ArchiveTemplateVersionsRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, + "/templates/{template}/versions/{templateversionname}": { + "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": "template", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Template version name", + "name": "templateversionname", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.TemplateVersion" + } + } + } + } + } + }, + "/templateversions/{templateversion}": { + "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": "templateversion", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.TemplateVersion" + } + } + } + }, + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Patch template version by ID", + "operationId": "patch-template-version-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversion", + "in": "path", + "required": true + }, + { + "description": "Patch template version request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.PatchTemplateVersionRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.TemplateVersion" + } + } + } + } + }, + "/templateversions/{templateversion}/archive": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Archive template version", + "operationId": "archive-template-version", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversion", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, + "/templateversions/{templateversion}/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": "templateversion", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, + "/templateversions/{templateversion}/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": "templateversion", + "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/{templateversion}/dry-run/{jobID}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "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": "templateversion", + "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/{templateversion}/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": "Job ID", + "name": "jobID", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversion", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, + "/templateversions/{templateversion}/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": "templateversion", + "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/{templateversion}/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": "templateversion", + "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" + } + } + } + } + } + }, + "/templateversions/{templateversion}/external-auth": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get external auth by template version", + "operationId": "get-external-auth-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.TemplateVersionExternalAuth" + } + } + } + } + } + }, + "/templateversions/{templateversion}/logs": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get logs by template version", + "operationId": "get-logs-by-template-version", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversion", + "in": "path", + "required": true + }, + { + "type": "integer", + "description": "Before log id", + "name": "before", + "in": "query" + }, + { + "type": "integer", + "description": "After log id", + "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/{templateversion}/parameters": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": ["Templates"], + "summary": "Removed: Get parameters by template version", + "operationId": "removed-get-parameters-by-template-version", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversion", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/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": "Template version ID", + "name": "templateversion", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceResource" + } + } + } + } + } + }, + "/templateversions/{templateversion}/rich-parameters": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get rich parameters by template version", + "operationId": "get-rich-parameters-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.TemplateVersionParameter" + } + } + } + } + } + }, + "/templateversions/{templateversion}/schema": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": ["Templates"], + "summary": "Removed: Get schema by template version", + "operationId": "removed-get-schema-by-template-version", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversion", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/templateversions/{templateversion}/unarchive": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Unarchive template version", + "operationId": "unarchive-template-version", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversion", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, + "/templateversions/{templateversion}/variables": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get template variables by template version", + "operationId": "get-template-variables-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.TemplateVersionVariable" + } + } + } + } + } + }, + "/updatecheck": { + "get": { + "produces": ["application/json"], + "tags": ["General"], + "summary": "Update check", + "operationId": "update-check", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.UpdateCheckResponse" + } + } + } + } + }, + "/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": [ + { + "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": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Authorization"], + "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/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": [ + { + "CoderSessionToken": [] + } + ], + "tags": ["Users"], + "summary": "OAuth 2.0 GitHub Callback", + "operationId": "oauth-20-github-callback", + "responses": { + "307": { + "description": "Temporary Redirect" + } + } + } + }, + "/users/oidc/callback": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": ["Users"], + "summary": "OpenID Connect Callback", + "operationId": "openid-connect-callback", + "responses": { + "307": { + "description": "Temporary Redirect" + } + } + } + }, + "/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}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Get user by name", + "operationId": "get-user-by-name", + "parameters": [ + { + "type": "string", + "description": "User ID, username, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.User" + } + } + } + }, + "delete": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "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" + } + } + } + }, + "/users/{user}/appearance": { + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Update user appearance settings", + "operationId": "update-user-appearance-settings", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "description": "New appearance settings", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateUserAppearanceSettingsRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.User" + } + } + } + } + }, + "/users/{user}/autofill-parameters": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Get autofill build parameters for user", + "operationId": "get-autofill-build-parameters-for-user", + "parameters": [ + { + "type": "string", + "description": "User ID, username, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Template ID", + "name": "template_id", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.UserParameter" + } + } + } + } + } + }, + "/users/{user}/convert-login": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Authorization"], + "summary": "Convert user from password to oauth authentication", + "operationId": "convert-user-from-password-to-oauth-authentication", + "parameters": [ + { + "description": "Convert request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.ConvertLoginRequest" + } + }, + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.OAuthConversionResponse" + } + } + } + } + }, + "/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": [ + { + "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": [] + } + ], + "consumes": ["application/json"], + "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}/keys/tokens/tokenconfig": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["General"], + "summary": "Get token config", + "operationId": "get-token-config", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.TokenConfig" + } + } + } + } + }, + "/users/{user}/keys/tokens/{keyname}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Get API key by token name", + "operationId": "get-api-key-by-token-name", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "string", + "description": "Key Name", + "name": "keyname", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.APIKey" + } + } + } + } + }, + "/users/{user}/keys/{keyid}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Get API key by ID", + "operationId": "get-api-key-by-id", + "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": [] + } + ], + "tags": ["Users"], + "summary": "Delete API key", + "operationId": "delete-api-key", + "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}/login-type": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Get user login type", + "operationId": "get-user-login-type", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.UserLoginType" + } + } + } + } + }, + "/users/{user}/notifications/preferences": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Notifications"], + "summary": "Get user notification preferences", + "operationId": "get-user-notification-preferences", + "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.NotificationPreference" + } + } + } + } + }, + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Notifications"], + "summary": "Update user notification preferences", + "operationId": "update-user-notification-preferences", + "parameters": [ + { + "description": "Preferences", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateUserNotificationPreferences" + } + }, + { + "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.NotificationPreference" + } + } + } + } + } + }, + "/users/{user}/organizations": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Get organizations by user", + "operationId": "get-organizations-by-user", + "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": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["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": { + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "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}/quiet-hours": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Get user quiet hours schedule", + "operationId": "get-user-quiet-hours-schedule", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "User ID", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.UserQuietHoursScheduleResponse" + } + } + } + } + }, + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Update user quiet hours schedule", + "operationId": "update-user-quiet-hours-schedule", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "User ID", + "name": "user", + "in": "path", + "required": true + }, + { + "description": "Update schedule request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateUserQuietHoursScheduleRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.UserQuietHoursScheduleResponse" + } + } + } + } + } + }, + "/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": [ + { + "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": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Workspaces"], + "summary": "Get workspace metadata by user and workspace name", + "operationId": "get-workspace-metadata-by-user-and-workspace-name", + "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": "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" + } + } + } + } + }, + "/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" + } + } + } + } + }, + "/users/{user}/workspaces": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "description": "Create a new workspace using a template. The request must\nspecify either the Template ID or the Template Version ID,\nnot both. If the Template ID is specified, the active version\nof the template will be used.", + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Workspaces"], + "summary": "Create user workspace", + "operationId": "create-user-workspace", + "parameters": [ + { + "type": "string", + "description": "Username, UUID, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "description": "Create workspace request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateWorkspaceRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Workspace" + } + } + } + } + }, + "/workspace-quota/{user}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Get workspace quota by user", + "operationId": "get-workspace-quota-by-user", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceQuota" + } + } + } + } + }, + "/workspaceagents/aws-instance-identity": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Agents"], + "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/agentsdk.AWSInstanceIdentityToken" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/agentsdk.AuthenticateResponse" + } + } + } + } + }, + "/workspaceagents/azure-instance-identity": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Agents"], + "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/agentsdk.AzureInstanceIdentityToken" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/agentsdk.AuthenticateResponse" + } + } + } + } + }, + "/workspaceagents/connection": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Agents"], + "summary": "Get connection info for workspace agent generic", + "operationId": "get-connection-info-for-workspace-agent-generic", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/workspacesdk.AgentConnectionInfo" + } + } + }, + "x-apidocgen": { + "skip": true + } + } + }, + "/workspaceagents/google-instance-identity": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Agents"], + "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/agentsdk.GoogleInstanceIdentityToken" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/agentsdk.AuthenticateResponse" + } + } + } + } + }, + "/workspaceagents/me/external-auth": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Agents"], + "summary": "Get workspace agent external auth", + "operationId": "get-workspace-agent-external-auth", + "parameters": [ + { + "type": "string", + "description": "Match", + "name": "match", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "Provider ID", + "name": "id", + "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/agentsdk.ExternalAuthResponse" + } + } + } + } + }, + "/workspaceagents/me/gitauth": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Agents"], + "summary": "Removed: Get workspace agent git auth", + "operationId": "removed-get-workspace-agent-git-auth", + "parameters": [ + { + "type": "string", + "description": "Match", + "name": "match", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "Provider ID", + "name": "id", + "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/agentsdk.ExternalAuthResponse" + } + } + } + } + }, + "/workspaceagents/me/gitsshkey": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "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/agentsdk.GitSSHKey" + } + } + } + } + }, + "/workspaceagents/me/log-source": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Agents"], + "summary": "Post workspace agent log source", + "operationId": "post-workspace-agent-log-source", + "parameters": [ + { + "description": "Log source request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/agentsdk.PostLogSourceRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceAgentLogSource" + } + } + } + } + }, + "/workspaceagents/me/logs": { + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Agents"], + "summary": "Patch workspace agent logs", + "operationId": "patch-workspace-agent-logs", + "parameters": [ + { + "description": "logs", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/agentsdk.PatchLogs" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, + "/workspaceagents/me/rpc": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": ["Agents"], + "summary": "Workspace agent RPC API", + "operationId": "workspace-agent-rpc-api", + "responses": { + "101": { + "description": "Switching Protocols" + } + }, + "x-apidocgen": { + "skip": true + } + } + }, + "/workspaceagents/{workspaceagent}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Agents"], + "summary": "Get workspace agent by ID", + "operationId": "get-workspace-agent-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace agent ID", + "name": "workspaceagent", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceAgent" + } + } + } + } + }, + "/workspaceagents/{workspaceagent}/connection": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Agents"], + "summary": "Get connection info for workspace agent", + "operationId": "get-connection-info-for-workspace-agent", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace agent ID", + "name": "workspaceagent", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/workspacesdk.AgentConnectionInfo" + } + } + } + } + }, + "/workspaceagents/{workspaceagent}/coordinate": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": ["Agents"], + "summary": "Coordinate workspace agent", + "operationId": "coordinate-workspace-agent", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace agent ID", + "name": "workspaceagent", + "in": "path", + "required": true + } + ], + "responses": { + "101": { + "description": "Switching Protocols" + } + } + } + }, + "/workspaceagents/{workspaceagent}/listening-ports": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Agents"], + "summary": "Get listening ports for workspace agent", + "operationId": "get-listening-ports-for-workspace-agent", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace agent ID", + "name": "workspaceagent", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceAgentListeningPortsResponse" + } + } + } + } + }, + "/workspaceagents/{workspaceagent}/logs": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Agents"], + "summary": "Get logs by workspace agent", + "operationId": "get-logs-by-workspace-agent", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace agent ID", + "name": "workspaceagent", + "in": "path", + "required": true + }, + { + "type": "integer", + "description": "Before log id", + "name": "before", + "in": "query" + }, + { + "type": "integer", + "description": "After log id", + "name": "after", + "in": "query" + }, + { + "type": "boolean", + "description": "Follow log stream", + "name": "follow", + "in": "query" + }, + { + "type": "boolean", + "description": "Disable compression for WebSocket connection", + "name": "no_compression", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceAgentLog" + } + } + } + } + } + }, + "/workspaceagents/{workspaceagent}/pty": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": ["Agents"], + "summary": "Open PTY to workspace agent", + "operationId": "open-pty-to-workspace-agent", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace agent ID", + "name": "workspaceagent", + "in": "path", + "required": true + } + ], + "responses": { + "101": { + "description": "Switching Protocols" + } + } + } + }, + "/workspaceagents/{workspaceagent}/startup-logs": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Agents"], + "summary": "Removed: Get logs by workspace agent", + "operationId": "removed-get-logs-by-workspace-agent", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace agent ID", + "name": "workspaceagent", + "in": "path", + "required": true + }, + { + "type": "integer", + "description": "Before log id", + "name": "before", + "in": "query" + }, + { + "type": "integer", + "description": "After log id", + "name": "after", + "in": "query" + }, + { + "type": "boolean", + "description": "Follow log stream", + "name": "follow", + "in": "query" + }, + { + "type": "boolean", + "description": "Disable compression for WebSocket connection", + "name": "no_compression", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceAgentLog" + } + } + } + } + } + }, + "/workspaceagents/{workspaceagent}/watch-metadata": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": ["Agents"], + "summary": "Watch for workspace agent metadata updates", + "operationId": "watch-for-workspace-agent-metadata-updates", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace agent ID", + "name": "workspaceagent", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Success" + } + }, + "x-apidocgen": { + "skip": true + } + } + }, + "/workspacebuilds/{workspacebuild}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Builds"], + "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": ["Builds"], + "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": ["Builds"], + "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}/parameters": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Builds"], + "summary": "Get build parameters for workspace build", + "operationId": "get-build-parameters-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.WorkspaceBuildParameter" + } + } + } + } + } + }, + "/workspacebuilds/{workspacebuild}/resources": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Builds"], + "summary": "Removed: Get workspace resources for workspace build", + "operationId": "removed-get-workspace-resources-for-workspace-build", + "deprecated": true, + "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": ["Builds"], + "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" + } + } + } + } + }, + "/workspaceproxies": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Get workspace proxies", + "operationId": "get-workspace-proxies", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.RegionsResponse-codersdk_WorkspaceProxy" + } + } + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Create workspace proxy", + "operationId": "create-workspace-proxy", + "parameters": [ + { + "description": "Create workspace proxy request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateWorkspaceProxyRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceProxy" + } + } + } + } + }, + "/workspaceproxies/me/app-stats": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "tags": ["Enterprise"], + "summary": "Report workspace app stats", + "operationId": "report-workspace-app-stats", + "parameters": [ + { + "description": "Report app stats request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/wsproxysdk.ReportAppStatsRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + } + }, + "x-apidocgen": { + "skip": true + } + } + }, + "/workspaceproxies/me/coordinate": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": ["Enterprise"], + "summary": "Workspace Proxy Coordinate", + "operationId": "workspace-proxy-coordinate", + "responses": { + "101": { + "description": "Switching Protocols" + } + }, + "x-apidocgen": { + "skip": true + } + } + }, + "/workspaceproxies/me/deregister": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "tags": ["Enterprise"], + "summary": "Deregister workspace proxy", + "operationId": "deregister-workspace-proxy", + "parameters": [ + { + "description": "Deregister workspace proxy request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/wsproxysdk.DeregisterWorkspaceProxyRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + } + }, + "x-apidocgen": { + "skip": true + } + } + }, + "/workspaceproxies/me/issue-signed-app-token": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Issue signed workspace app token", + "operationId": "issue-signed-workspace-app-token", + "parameters": [ + { + "description": "Issue signed app token request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/workspaceapps.IssueTokenRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/wsproxysdk.IssueSignedAppTokenResponse" + } + } + }, + "x-apidocgen": { + "skip": true + } + } + }, + "/workspaceproxies/me/register": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Register workspace proxy", + "operationId": "register-workspace-proxy", + "parameters": [ + { + "description": "Register workspace proxy request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/wsproxysdk.RegisterWorkspaceProxyRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/wsproxysdk.RegisterWorkspaceProxyResponse" + } + } + }, + "x-apidocgen": { + "skip": true + } + } + }, + "/workspaceproxies/{workspaceproxy}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Get workspace proxy", + "operationId": "get-workspace-proxy", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Proxy ID or name", + "name": "workspaceproxy", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceProxy" + } + } + } + }, + "delete": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Delete workspace proxy", + "operationId": "delete-workspace-proxy", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Proxy ID or name", + "name": "workspaceproxy", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + }, + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Update workspace proxy", + "operationId": "update-workspace-proxy", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Proxy ID or name", + "name": "workspaceproxy", + "in": "path", + "required": true + }, + { + "description": "Update workspace proxy request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.PatchWorkspaceProxy" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceProxy" + } + } + } + } + }, + "/workspaces": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Workspaces"], + "summary": "List workspaces", + "operationId": "list-workspaces", + "parameters": [ + { + "type": "string", + "description": "Search query in the format `key:value`. Available keys are: owner, template, name, status, has-agent, dormant, last_used_after, last_used_before.", + "name": "q", + "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.WorkspacesResponse" + } + } + } + } + }, + "/workspaces/{workspace}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Workspaces"], + "summary": "Get workspace metadata by ID", + "operationId": "get-workspace-metadata-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "workspace", + "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" + } + } + } + }, + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "tags": ["Workspaces"], + "summary": "Update workspace metadata by ID", + "operationId": "update-workspace-metadata-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "workspace", + "in": "path", + "required": true + }, + { + "description": "Metadata update request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateWorkspaceRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/workspaces/{workspace}/autostart": { + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "tags": ["Workspaces"], + "summary": "Update workspace autostart schedule by ID", + "operationId": "update-workspace-autostart-schedule-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "workspace", + "in": "path", + "required": true + }, + { + "description": "Schedule update request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateWorkspaceAutostartRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/workspaces/{workspace}/autoupdates": { + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "tags": ["Workspaces"], + "summary": "Update workspace automatic updates by ID", + "operationId": "update-workspace-automatic-updates-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "workspace", + "in": "path", + "required": true + }, + { + "description": "Automatic updates request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateWorkspaceAutomaticUpdatesRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/workspaces/{workspace}/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": "workspace", + "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": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Builds"], + "summary": "Create workspace build", + "operationId": "create-workspace-build", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "workspace", + "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}/dormant": { + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Workspaces"], + "summary": "Update workspace dormancy status by id.", + "operationId": "update-workspace-dormancy-status-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "workspace", + "in": "path", + "required": true + }, + { + "description": "Make a workspace dormant or active", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateWorkspaceDormancy" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Workspace" + } + } + } + } + }, + "/workspaces/{workspace}/extend": { + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Workspaces"], + "summary": "Extend workspace deadline by ID", + "operationId": "extend-workspace-deadline-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "workspace", + "in": "path", + "required": true + }, + { + "description": "Extend deadline update request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.PutExtendWorkspaceRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, + "/workspaces/{workspace}/favorite": { + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": ["Workspaces"], + "summary": "Favorite workspace by ID.", + "operationId": "favorite-workspace-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "workspace", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + }, + "delete": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": ["Workspaces"], + "summary": "Unfavorite workspace by ID.", + "operationId": "unfavorite-workspace-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "workspace", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/workspaces/{workspace}/port-share": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["PortSharing"], + "summary": "Get workspace agent port shares", + "operationId": "get-workspace-agent-port-shares", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "workspace", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceAgentPortShares" + } + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["PortSharing"], + "summary": "Upsert workspace agent port share", + "operationId": "upsert-workspace-agent-port-share", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "workspace", + "in": "path", + "required": true + }, + { + "description": "Upsert port sharing level request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpsertWorkspaceAgentPortShareRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceAgentPortShare" + } + } + } + }, + "delete": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "tags": ["PortSharing"], + "summary": "Get workspace agent port shares", + "operationId": "get-workspace-agent-port-shares", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "workspace", + "in": "path", + "required": true + }, + { + "description": "Delete port sharing level request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.DeleteWorkspaceAgentPortShareRequest" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/workspaces/{workspace}/resolve-autostart": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Workspaces"], + "summary": "Resolve workspace autostart by id.", + "operationId": "resolve-workspace-autostart-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "workspace", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.ResolveAutostartResponse" + } + } + } + } + }, + "/workspaces/{workspace}/ttl": { + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "tags": ["Workspaces"], + "summary": "Update workspace TTL by ID", + "operationId": "update-workspace-ttl-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "workspace", + "in": "path", + "required": true + }, + { + "description": "Workspace TTL update request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateWorkspaceTTLRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/workspaces/{workspace}/usage": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "tags": ["Workspaces"], + "summary": "Post Workspace Usage by ID", + "operationId": "post-workspace-usage-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "workspace", + "in": "path", + "required": true + }, + { + "description": "Post workspace usage request", + "name": "request", + "in": "body", + "schema": { + "$ref": "#/definitions/codersdk.PostWorkspaceUsageRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/workspaces/{workspace}/watch": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["text/event-stream"], + "tags": ["Workspaces"], + "summary": "Watch workspace by ID", + "operationId": "watch-workspace-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "workspace", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + } + }, + "definitions": { + "agentsdk.AWSInstanceIdentityToken": { + "type": "object", + "required": ["document", "signature"], + "properties": { + "document": { + "type": "string" + }, + "signature": { + "type": "string" + } + } + }, + "agentsdk.AuthenticateResponse": { + "type": "object", + "properties": { + "session_token": { + "type": "string" + } + } + }, + "agentsdk.AzureInstanceIdentityToken": { + "type": "object", + "required": ["encoding", "signature"], + "properties": { + "encoding": { + "type": "string" + }, + "signature": { + "type": "string" + } + } + }, + "agentsdk.ExternalAuthResponse": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "password": { + "type": "string" + }, + "token_extra": { + "type": "object", + "additionalProperties": true + }, + "type": { + "type": "string" + }, + "url": { + "type": "string" + }, + "username": { + "description": "Deprecated: Only supported on `/workspaceagents/me/gitauth`\nfor backwards compatibility.", + "type": "string" + } + } + }, + "agentsdk.GitSSHKey": { + "type": "object", + "properties": { + "private_key": { + "type": "string" + }, + "public_key": { + "type": "string" + } + } + }, + "agentsdk.GoogleInstanceIdentityToken": { + "type": "object", + "required": ["json_web_token"], + "properties": { + "json_web_token": { + "type": "string" + } + } + }, + "agentsdk.Log": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "level": { + "$ref": "#/definitions/codersdk.LogLevel" + }, + "output": { + "type": "string" + } + } + }, + "agentsdk.PatchLogs": { + "type": "object", + "properties": { + "log_source_id": { + "type": "string" + }, + "logs": { + "type": "array", + "items": { + "$ref": "#/definitions/agentsdk.Log" + } + } + } + }, + "agentsdk.PostLogSourceRequest": { + "type": "object", + "properties": { + "display_name": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "id": { + "description": "ID is a unique identifier for the log source.\nIt is scoped to a workspace agent, and can be statically\ndefined inside code to prevent duplicate sources from being\ncreated for the same agent.", + "type": "string" + } + } + }, + "coderd.SCIMUser": { + "type": "object", + "properties": { + "active": { + "type": "boolean" + }, + "emails": { + "type": "array", + "items": { + "type": "object", + "properties": { + "display": { + "type": "string" + }, + "primary": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": { + "type": "string", + "format": "email" + } + } + } + }, + "groups": { + "type": "array", + "items": {} + }, + "id": { + "type": "string" + }, + "meta": { + "type": "object", + "properties": { + "resourceType": { + "type": "string" + } + } + }, + "name": { + "type": "object", + "properties": { + "familyName": { + "type": "string" + }, + "givenName": { + "type": "string" + } + } + }, + "schemas": { + "type": "array", + "items": { + "type": "string" + } + }, + "userName": { + "type": "string" + } + } + }, + "coderd.cspViolation": { + "type": "object", + "properties": { + "csp-report": { + "type": "object", + "additionalProperties": true + } + } + }, + "codersdk.ACLAvailable": { + "type": "object", + "properties": { + "groups": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Group" + } + }, + "users": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.ReducedUser" + } + } + } + }, + "codersdk.APIKey": { + "type": "object", + "required": [ + "created_at", + "expires_at", + "id", + "last_used", + "lifetime_seconds", + "login_type", + "scope", + "token_name", + "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": { + "enum": ["password", "github", "oidc", "token"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.LoginType" + } + ] + }, + "scope": { + "enum": ["all", "application_connect"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.APIKeyScope" + } + ] + }, + "token_name": { + "type": "string" + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "user_id": { + "type": "string", + "format": "uuid" + } + } + }, + "codersdk.APIKeyScope": { + "type": "string", + "enum": ["all", "application_connect"], + "x-enum-varnames": ["APIKeyScopeAll", "APIKeyScopeApplicationConnect"] + }, + "codersdk.AddLicenseRequest": { + "type": "object", + "required": ["license"], + "properties": { + "license": { + "type": "string" + } + } + }, + "codersdk.AgentSubsystem": { + "type": "string", + "enum": ["envbox", "envbuilder", "exectrace"], + "x-enum-varnames": [ + "AgentSubsystemEnvbox", + "AgentSubsystemEnvbuilder", + "AgentSubsystemExectrace" + ] + }, + "codersdk.AppHostResponse": { + "type": "object", + "properties": { + "host": { + "description": "Host is the externally accessible URL for the Coder instance.", + "type": "string" + } + } + }, + "codersdk.AppearanceConfig": { + "type": "object", + "properties": { + "announcement_banners": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.BannerConfig" + } + }, + "application_name": { + "type": "string" + }, + "logo_url": { + "type": "string" + }, + "service_banner": { + "description": "Deprecated: ServiceBanner has been replaced by AnnouncementBanners.", + "allOf": [ + { + "$ref": "#/definitions/codersdk.BannerConfig" + } + ] + }, + "support_links": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.LinkConfig" + } + } + } + }, + "codersdk.ArchiveTemplateVersionsRequest": { + "type": "object", + "properties": { + "all": { + "description": "By default, only failed versions are archived. Set this to true\nto archive all unused versions regardless of job status.", + "type": "boolean" + } + } + }, + "codersdk.AssignableRoles": { + "type": "object", + "properties": { + "assignable": { + "type": "boolean" + }, + "built_in": { + "description": "BuiltIn roles are immutable", + "type": "boolean" + }, + "display_name": { + "type": "string" + }, + "name": { + "type": "string" + }, + "organization_id": { + "type": "string", + "format": "uuid" + }, + "organization_permissions": { + "description": "OrganizationPermissions are specific for the organization in the field 'OrganizationID' above.", + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Permission" + } + }, + "site_permissions": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Permission" + } + }, + "user_permissions": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Permission" + } + } + } + }, + "codersdk.AuditAction": { + "type": "string", + "enum": [ + "create", + "write", + "delete", + "start", + "stop", + "login", + "logout", + "register" + ], + "x-enum-varnames": [ + "AuditActionCreate", + "AuditActionWrite", + "AuditActionDelete", + "AuditActionStart", + "AuditActionStop", + "AuditActionLogin", + "AuditActionLogout", + "AuditActionRegister" + ] + }, + "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": { + "$ref": "#/definitions/codersdk.AuditAction" + }, + "additional_fields": { + "type": "array", + "items": { + "type": "integer" + } + }, + "description": { + "type": "string" + }, + "diff": { + "$ref": "#/definitions/codersdk.AuditDiff" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "ip": { + "type": "string" + }, + "is_deleted": { + "type": "boolean" + }, + "organization": { + "$ref": "#/definitions/codersdk.MinimalOrganization" + }, + "organization_id": { + "description": "Deprecated: Use 'organization.id' instead.", + "type": "string", + "format": "uuid" + }, + "request_id": { + "type": "string", + "format": "uuid" + }, + "resource_icon": { + "type": "string" + }, + "resource_id": { + "type": "string", + "format": "uuid" + }, + "resource_link": { + "type": "string" + }, + "resource_target": { + "description": "ResourceTarget is the name of the resource.", + "type": "string" + }, + "resource_type": { + "$ref": "#/definitions/codersdk.ResourceType" + }, + "status_code": { + "type": "integer" + }, + "time": { + "type": "string", + "format": "date-time" + }, + "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.AuthMethod": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + } + } + }, + "codersdk.AuthMethods": { + "type": "object", + "properties": { + "github": { + "$ref": "#/definitions/codersdk.AuthMethod" + }, + "oidc": { + "$ref": "#/definitions/codersdk.OIDCAuthMethod" + }, + "password": { + "$ref": "#/definitions/codersdk.AuthMethod" + }, + "terms_of_service_url": { + "type": "string" + } + } + }, + "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": { + "enum": ["create", "read", "update", "delete"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.RBACAction" + } + ] + }, + "object": { + "description": "Object can represent a \"set\" of objects, such as: all workspaces in an organization, all workspaces owned by me, and all workspaces across the entire product.\nWhen defining an object, use the most specific language when possible to\nproduce the smallest set. Meaning to set as many fields on 'Object' as\nyou can. Example, if you want to check if you can update all workspaces\nowned by 'me', try to also add an 'OrganizationID' to the settings.\nOmitting the 'OrganizationID' could produce the incorrect value, as\nworkspaces have both `user` and `organization` owners.", + "allOf": [ + { + "$ref": "#/definitions/codersdk.AuthorizationObject" + } + ] + } + } + }, + "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": { + "any_org": { + "description": "AnyOrgOwner (optional) will disregard the org_owner when checking for permissions.\nThis cannot be set to true if the OrganizationID is set.", + "type": "boolean" + }, + "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.", + "allOf": [ + { + "$ref": "#/definitions/codersdk.RBACResource" + } + ] + } + } + }, + "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.AutomaticUpdates": { + "type": "string", + "enum": ["always", "never"], + "x-enum-varnames": ["AutomaticUpdatesAlways", "AutomaticUpdatesNever"] + }, + "codersdk.BannerConfig": { + "type": "object", + "properties": { + "background_color": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "message": { + "type": "string" + } + } + }, + "codersdk.BuildInfoResponse": { + "type": "object", + "properties": { + "agent_api_version": { + "description": "AgentAPIVersion is the current version of the Agent API (back versions\nMAY still be supported).", + "type": "string" + }, + "dashboard_url": { + "description": "DashboardURL is the URL to hit the deployment's dashboard.\nFor external workspace proxies, this is the coderd they are connected\nto.", + "type": "string" + }, + "deployment_id": { + "description": "DeploymentID is the unique identifier for this deployment.", + "type": "string" + }, + "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" + }, + "telemetry": { + "description": "Telemetry is a boolean that indicates whether telemetry is enabled.", + "type": "boolean" + }, + "upgrade_message": { + "description": "UpgradeMessage is the message displayed to users when an outdated client\nis detected.", + "type": "string" + }, + "version": { + "description": "Version returns the semantic version of the build.", + "type": "string" + }, + "workspace_proxy": { + "type": "boolean" + } + } + }, + "codersdk.BuildReason": { + "type": "string", + "enum": ["initiator", "autostart", "autostop"], + "x-enum-varnames": [ + "BuildReasonInitiator", + "BuildReasonAutostart", + "BuildReasonAutostop" + ] + }, + "codersdk.ConnectionLatency": { + "type": "object", + "properties": { + "p50": { + "type": "number", + "example": 31.312 + }, + "p95": { + "type": "number", + "example": 119.832 + } + } + }, + "codersdk.ConvertLoginRequest": { + "type": "object", + "required": ["password", "to_type"], + "properties": { + "password": { + "type": "string" + }, + "to_type": { + "description": "ToType is the login type to convert to.", + "allOf": [ + { + "$ref": "#/definitions/codersdk.LoginType" + } + ] + } + } + }, + "codersdk.CreateFirstUserRequest": { + "type": "object", + "required": ["email", "password", "username"], + "properties": { + "email": { + "type": "string" + }, + "name": { + "type": "string" + }, + "password": { + "type": "string" + }, + "trial": { + "type": "boolean" + }, + "trial_info": { + "$ref": "#/definitions/codersdk.CreateFirstUserTrialInfo" + }, + "username": { + "type": "string" + } + } + }, + "codersdk.CreateFirstUserResponse": { + "type": "object", + "properties": { + "organization_id": { + "type": "string", + "format": "uuid" + }, + "user_id": { + "type": "string", + "format": "uuid" + } + } + }, + "codersdk.CreateFirstUserTrialInfo": { + "type": "object", + "properties": { + "company_name": { + "type": "string" + }, + "country": { + "type": "string" + }, + "developers": { + "type": "string" + }, + "first_name": { + "type": "string" + }, + "job_title": { + "type": "string" + }, + "last_name": { + "type": "string" + }, + "phone_number": { + "type": "string" + } + } + }, + "codersdk.CreateGroupRequest": { + "type": "object", + "required": ["name"], + "properties": { + "avatar_url": { + "type": "string" + }, + "display_name": { + "type": "string" + }, + "name": { + "type": "string" + }, + "quota_allowance": { + "type": "integer" + } + } + }, + "codersdk.CreateOrganizationRequest": { + "type": "object", + "required": ["name"], + "properties": { + "description": { + "type": "string" + }, + "display_name": { + "description": "DisplayName will default to the same value as `Name` if not provided.", + "type": "string" + }, + "icon": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "codersdk.CreateProvisionerKeyResponse": { + "type": "object", + "properties": { + "key": { + "type": "string" + } + } + }, + "codersdk.CreateTemplateRequest": { + "type": "object", + "required": ["name", "template_version_id"], + "properties": { + "activity_bump_ms": { + "description": "ActivityBumpMillis allows optionally specifying the activity bump\nduration for all workspaces created from this template. Defaults to 1h\nbut can be set to 0 to disable activity bumping.", + "type": "integer" + }, + "allow_user_autostart": { + "description": "AllowUserAutostart allows users to set a schedule for autostarting their\nworkspace. By default this is true. This can only be disabled when using\nan enterprise license.", + "type": "boolean" + }, + "allow_user_autostop": { + "description": "AllowUserAutostop allows users to set a custom workspace TTL to use in\nplace of the template's DefaultTTL field. By default this is true. If\nfalse, the DefaultTTL will always be used. This can only be disabled when\nusing an enterprise license.", + "type": "boolean" + }, + "allow_user_cancel_workspace_jobs": { + "description": "Allow users to cancel in-progress workspace jobs.\n*bool as the default value is \"true\".", + "type": "boolean" + }, + "autostart_requirement": { + "description": "AutostartRequirement allows optionally specifying the autostart allowed days\nfor workspaces created from this template. This is an enterprise feature.", + "allOf": [ + { + "$ref": "#/definitions/codersdk.TemplateAutostartRequirement" + } + ] + }, + "autostop_requirement": { + "description": "AutostopRequirement allows optionally specifying the autostop requirement\nfor workspaces created from this template. This is an enterprise feature.", + "allOf": [ + { + "$ref": "#/definitions/codersdk.TemplateAutostopRequirement" + } + ] + }, + "default_ttl_ms": { + "description": "DefaultTTLMillis allows optionally specifying the default TTL\nfor all workspaces created from this template.", + "type": "integer" + }, + "delete_ttl_ms": { + "description": "TimeTilDormantAutoDeleteMillis allows optionally specifying the max lifetime before Coder\npermanently deletes dormant 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" + }, + "disable_everyone_group_access": { + "description": "DisableEveryoneGroupAccess allows optionally disabling the default\nbehavior of granting the 'everyone' group access to use the template.\nIf this is set to true, the template will not be available to all users,\nand must be explicitly granted to users or groups in the permissions settings\nof the template.", + "type": "boolean" + }, + "display_name": { + "description": "DisplayName is the displayed name of the template.", + "type": "string" + }, + "dormant_ttl_ms": { + "description": "TimeTilDormantMillis allows optionally specifying the max lifetime before Coder\nlocks inactive workspaces created from this template.", + "type": "integer" + }, + "failure_ttl_ms": { + "description": "FailureTTLMillis allows optionally specifying the max lifetime before Coder\nstops all resources for failed workspaces created from this template.", + "type": "integer" + }, + "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" + }, + "require_active_version": { + "description": "RequireActiveVersion mandates that workspaces are built with the active\ntemplate version.", + "type": "boolean" + }, + "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", + "format": "uuid" + } + } + }, + "codersdk.CreateTemplateVersionDryRunRequest": { + "type": "object", + "properties": { + "rich_parameter_values": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceBuildParameter" + } + }, + "user_variable_values": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.VariableValue" + } + }, + "workspace_name": { + "type": "string" + } + } + }, + "codersdk.CreateTemplateVersionRequest": { + "type": "object", + "required": ["provisioner", "storage_method"], + "properties": { + "example_id": { + "type": "string" + }, + "file_id": { + "type": "string", + "format": "uuid" + }, + "message": { + "type": "string" + }, + "name": { + "type": "string" + }, + "provisioner": { + "type": "string", + "enum": ["terraform", "echo"] + }, + "storage_method": { + "enum": ["file"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.ProvisionerStorageMethod" + } + ] + }, + "tags": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "template_id": { + "description": "TemplateID optionally associates a version with a template.", + "type": "string", + "format": "uuid" + }, + "user_variable_values": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.VariableValue" + } + } + } + }, + "codersdk.CreateTestAuditLogRequest": { + "type": "object", + "properties": { + "action": { + "enum": ["create", "write", "delete", "start", "stop"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.AuditAction" + } + ] + }, + "additional_fields": { + "type": "array", + "items": { + "type": "integer" + } + }, + "build_reason": { + "enum": ["autostart", "autostop", "initiator"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.BuildReason" + } + ] + }, + "organization_id": { + "type": "string", + "format": "uuid" + }, + "resource_id": { + "type": "string", + "format": "uuid" + }, + "resource_type": { + "enum": [ + "template", + "template_version", + "user", + "workspace", + "workspace_build", + "git_ssh_key", + "auditable_group" + ], + "allOf": [ + { + "$ref": "#/definitions/codersdk.ResourceType" + } + ] + }, + "time": { + "type": "string", + "format": "date-time" + } + } + }, + "codersdk.CreateTokenRequest": { + "type": "object", + "properties": { + "lifetime": { + "type": "integer" + }, + "scope": { + "enum": ["all", "application_connect"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.APIKeyScope" + } + ] + }, + "token_name": { + "type": "string" + } + } + }, + "codersdk.CreateUserRequest": { + "type": "object", + "required": ["email", "username"], + "properties": { + "disable_login": { + "description": "DisableLogin sets the user's login type to 'none'. This prevents the user\nfrom being able to use a password or any other authentication method to login.\nDeprecated: Set UserLoginType=LoginTypeDisabled instead.", + "type": "boolean" + }, + "email": { + "type": "string", + "format": "email" + }, + "login_type": { + "description": "UserLoginType defaults to LoginTypePassword.", + "allOf": [ + { + "$ref": "#/definitions/codersdk.LoginType" + } + ] + }, + "name": { + "type": "string" + }, + "organization_id": { + "type": "string", + "format": "uuid" + }, + "password": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "codersdk.CreateWorkspaceBuildRequest": { + "type": "object", + "required": ["transition"], + "properties": { + "dry_run": { + "type": "boolean" + }, + "log_level": { + "description": "Log level changes the default logging verbosity of a provider (\"info\" if empty).", + "enum": ["debug"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.ProvisionerLogLevel" + } + ] + }, + "orphan": { + "description": "Orphan may be set for the Destroy transition.", + "type": "boolean" + }, + "rich_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.WorkspaceBuildParameter" + } + }, + "state": { + "type": "array", + "items": { + "type": "integer" + } + }, + "template_version_id": { + "type": "string", + "format": "uuid" + }, + "transition": { + "enum": ["create", "start", "stop", "delete"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.WorkspaceTransition" + } + ] + } + } + }, + "codersdk.CreateWorkspaceProxyRequest": { + "type": "object", + "required": ["name"], + "properties": { + "display_name": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "codersdk.CreateWorkspaceRequest": { + "description": "CreateWorkspaceRequest provides options for creating a new workspace. Only one of TemplateID or TemplateVersionID can be specified, not both. If TemplateID is specified, the active version of the template will be used.", + "type": "object", + "required": ["name"], + "properties": { + "automatic_updates": { + "$ref": "#/definitions/codersdk.AutomaticUpdates" + }, + "autostart_schedule": { + "type": "string" + }, + "name": { + "type": "string" + }, + "rich_parameter_values": { + "description": "RichParameterValues allows for additional parameters to be provided\nduring the initial provision.", + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceBuildParameter" + } + }, + "template_id": { + "description": "TemplateID specifies which template should be used for creating the workspace.", + "type": "string", + "format": "uuid" + }, + "template_version_id": { + "description": "TemplateVersionID can be used to specify a specific version of a template for creating the workspace.", + "type": "string", + "format": "uuid" + }, + "ttl_ms": { + "type": "integer" + } + } + }, + "codersdk.CustomRoleRequest": { + "type": "object", + "properties": { + "display_name": { + "type": "string" + }, + "name": { + "type": "string" + }, + "organization_permissions": { + "description": "OrganizationPermissions are specific to the organization the role belongs to.", + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Permission" + } + }, + "site_permissions": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Permission" + } + }, + "user_permissions": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Permission" + } + } + } + }, + "codersdk.DAUEntry": { + "type": "object", + "properties": { + "amount": { + "type": "integer" + }, + "date": { + "description": "Date is a string formatted as 2024-01-31.\nTimezone and time information is not included.", + "type": "string" + } + } + }, + "codersdk.DAUsResponse": { + "type": "object", + "properties": { + "entries": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.DAUEntry" + } + }, + "tz_hour_offset": { + "type": "integer" + } + } + }, + "codersdk.DERP": { + "type": "object", + "properties": { + "config": { + "$ref": "#/definitions/codersdk.DERPConfig" + }, + "server": { + "$ref": "#/definitions/codersdk.DERPServerConfig" + } + } + }, + "codersdk.DERPConfig": { + "type": "object", + "properties": { + "block_direct": { + "type": "boolean" + }, + "force_websockets": { + "type": "boolean" + }, + "path": { + "type": "string" + }, + "url": { + "type": "string" + } + } + }, + "codersdk.DERPRegion": { + "type": "object", + "properties": { + "latency_ms": { + "type": "number" + }, + "preferred": { + "type": "boolean" + } + } + }, + "codersdk.DERPServerConfig": { + "type": "object", + "properties": { + "enable": { + "type": "boolean" + }, + "region_code": { + "type": "string" + }, + "region_id": { + "type": "integer" + }, + "region_name": { + "type": "string" + }, + "relay_url": { + "$ref": "#/definitions/serpent.URL" + }, + "stun_addresses": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "codersdk.DangerousConfig": { + "type": "object", + "properties": { + "allow_all_cors": { + "type": "boolean" + }, + "allow_path_app_sharing": { + "type": "boolean" + }, + "allow_path_app_site_owner_access": { + "type": "boolean" + } + } + }, + "codersdk.DeleteWorkspaceAgentPortShareRequest": { + "type": "object", + "properties": { + "agent_name": { + "type": "string" + }, + "port": { + "type": "integer" + } + } + }, + "codersdk.DeploymentConfig": { + "type": "object", + "properties": { + "config": { + "$ref": "#/definitions/codersdk.DeploymentValues" + }, + "options": { + "type": "array", + "items": { + "$ref": "#/definitions/serpent.Option" + } + } + } + }, + "codersdk.DeploymentStats": { + "type": "object", + "properties": { + "aggregated_from": { + "description": "AggregatedFrom is the time in which stats are aggregated from.\nThis might be back in time a specific duration or interval.", + "type": "string", + "format": "date-time" + }, + "collected_at": { + "description": "CollectedAt is the time in which stats are collected at.", + "type": "string", + "format": "date-time" + }, + "next_update_at": { + "description": "NextUpdateAt is the time when the next batch of stats will\nbe updated.", + "type": "string", + "format": "date-time" + }, + "session_count": { + "$ref": "#/definitions/codersdk.SessionCountDeploymentStats" + }, + "workspaces": { + "$ref": "#/definitions/codersdk.WorkspaceDeploymentStats" + } + } + }, + "codersdk.DeploymentValues": { + "type": "object", + "properties": { + "access_url": { + "$ref": "#/definitions/serpent.URL" + }, + "address": { + "description": "DEPRECATED: Use HTTPAddress or TLS.Address instead.", + "allOf": [ + { + "$ref": "#/definitions/serpent.HostPort" + } + ] + }, + "agent_fallback_troubleshooting_url": { + "$ref": "#/definitions/serpent.URL" + }, + "agent_stat_refresh_interval": { + "type": "integer" + }, + "allow_workspace_renames": { + "type": "boolean" + }, + "autobuild_poll_interval": { + "type": "integer" + }, + "browser_only": { + "type": "boolean" + }, + "cache_directory": { + "type": "string" + }, + "cli_upgrade_message": { + "type": "string" + }, + "config": { + "type": "string" + }, + "config_ssh": { + "$ref": "#/definitions/codersdk.SSHConfig" + }, + "dangerous": { + "$ref": "#/definitions/codersdk.DangerousConfig" + }, + "derp": { + "$ref": "#/definitions/codersdk.DERP" + }, + "disable_owner_workspace_exec": { + "type": "boolean" + }, + "disable_password_auth": { + "type": "boolean" + }, + "disable_path_apps": { + "type": "boolean" + }, + "docs_url": { + "$ref": "#/definitions/serpent.URL" + }, + "enable_terraform_debug_mode": { + "type": "boolean" + }, + "experiments": { + "type": "array", + "items": { + "type": "string" + } + }, + "external_auth": { + "$ref": "#/definitions/serpent.Struct-array_codersdk_ExternalAuthConfig" + }, + "external_token_encryption_keys": { + "type": "array", + "items": { + "type": "string" + } + }, + "healthcheck": { + "$ref": "#/definitions/codersdk.HealthcheckConfig" + }, + "http_address": { + "description": "HTTPAddress is a string because it may be set to zero to disable.", + "type": "string" + }, + "in_memory_database": { + "type": "boolean" + }, + "job_hang_detector_interval": { + "type": "integer" + }, + "logging": { + "$ref": "#/definitions/codersdk.LoggingConfig" + }, + "metrics_cache_refresh_interval": { + "type": "integer" + }, + "notifications": { + "$ref": "#/definitions/codersdk.NotificationsConfig" + }, + "oauth2": { + "$ref": "#/definitions/codersdk.OAuth2Config" + }, + "oidc": { + "$ref": "#/definitions/codersdk.OIDCConfig" + }, + "pg_auth": { + "type": "string" + }, + "pg_connection_url": { + "type": "string" + }, + "pprof": { + "$ref": "#/definitions/codersdk.PprofConfig" + }, + "prometheus": { + "$ref": "#/definitions/codersdk.PrometheusConfig" + }, + "provisioner": { + "$ref": "#/definitions/codersdk.ProvisionerConfig" + }, + "proxy_health_status_interval": { + "type": "integer" + }, + "proxy_trusted_headers": { + "type": "array", + "items": { + "type": "string" + } + }, + "proxy_trusted_origins": { + "type": "array", + "items": { + "type": "string" + } + }, + "rate_limit": { + "$ref": "#/definitions/codersdk.RateLimitConfig" + }, + "redirect_to_access_url": { + "type": "boolean" + }, + "scim_api_key": { + "type": "string" + }, + "secure_auth_cookie": { + "type": "boolean" + }, + "session_lifetime": { + "$ref": "#/definitions/codersdk.SessionLifetime" + }, + "ssh_keygen_algorithm": { + "type": "string" + }, + "strict_transport_security": { + "type": "integer" + }, + "strict_transport_security_options": { + "type": "array", + "items": { + "type": "string" + } + }, + "support": { + "$ref": "#/definitions/codersdk.SupportConfig" + }, + "swagger": { + "$ref": "#/definitions/codersdk.SwaggerConfig" + }, + "telemetry": { + "$ref": "#/definitions/codersdk.TelemetryConfig" + }, + "terms_of_service_url": { + "type": "string" + }, + "tls": { + "$ref": "#/definitions/codersdk.TLSConfig" + }, + "trace": { + "$ref": "#/definitions/codersdk.TraceConfig" + }, + "update_check": { + "type": "boolean" + }, + "user_quiet_hours_schedule": { + "$ref": "#/definitions/codersdk.UserQuietHoursScheduleConfig" + }, + "verbose": { + "type": "boolean" + }, + "web_terminal_renderer": { + "type": "string" + }, + "wgtunnel_host": { + "type": "string" + }, + "wildcard_access_url": { + "type": "string" + }, + "write_config": { + "type": "boolean" + } + } + }, + "codersdk.DisplayApp": { + "type": "string", + "enum": [ + "vscode", + "vscode_insiders", + "web_terminal", + "port_forwarding_helper", + "ssh_helper" + ], + "x-enum-varnames": [ + "DisplayAppVSCodeDesktop", + "DisplayAppVSCodeInsiders", + "DisplayAppWebTerminal", + "DisplayAppPortForward", + "DisplayAppSSH" + ] + }, + "codersdk.Entitlement": { + "type": "string", + "enum": ["entitled", "grace_period", "not_entitled"], + "x-enum-varnames": [ + "EntitlementEntitled", + "EntitlementGracePeriod", + "EntitlementNotEntitled" + ] + }, + "codersdk.Entitlements": { + "type": "object", + "properties": { + "errors": { + "type": "array", + "items": { + "type": "string" + } + }, + "features": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/codersdk.Feature" + } + }, + "has_license": { + "type": "boolean" + }, + "refreshed_at": { + "type": "string", + "format": "date-time" + }, + "require_telemetry": { + "type": "boolean" + }, + "trial": { + "type": "boolean" + }, + "warnings": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "codersdk.Experiment": { + "type": "string", + "enum": [ + "example", + "auto-fill-parameters", + "multi-organization", + "custom-roles", + "notifications", + "workspace-usage" + ], + "x-enum-comments": { + "ExperimentAutoFillParameters": "This should not be taken out of experiments until we have redesigned the feature.", + "ExperimentCustomRoles": "Allows creating runtime custom roles.", + "ExperimentExample": "This isn't used for anything.", + "ExperimentMultiOrganization": "Requires organization context for interactions, default org is assumed.", + "ExperimentNotifications": "Sends notifications via SMTP and webhooks following certain events.", + "ExperimentWorkspaceUsage": "Enables the new workspace usage tracking." + }, + "x-enum-varnames": [ + "ExperimentExample", + "ExperimentAutoFillParameters", + "ExperimentMultiOrganization", + "ExperimentCustomRoles", + "ExperimentNotifications", + "ExperimentWorkspaceUsage" + ] + }, + "codersdk.ExternalAuth": { + "type": "object", + "properties": { + "app_install_url": { + "description": "AppInstallURL is the URL to install the app.", + "type": "string" + }, + "app_installable": { + "description": "AppInstallable is true if the request for app installs was successful.", + "type": "boolean" + }, + "authenticated": { + "type": "boolean" + }, + "device": { + "type": "boolean" + }, + "display_name": { + "type": "string" + }, + "installations": { + "description": "AppInstallations are the installations that the user has access to.", + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.ExternalAuthAppInstallation" + } + }, + "user": { + "description": "User is the user that authenticated with the provider.", + "allOf": [ + { + "$ref": "#/definitions/codersdk.ExternalAuthUser" + } + ] + } + } + }, + "codersdk.ExternalAuthAppInstallation": { + "type": "object", + "properties": { + "account": { + "$ref": "#/definitions/codersdk.ExternalAuthUser" + }, + "configure_url": { + "type": "string" + }, + "id": { + "type": "integer" + } + } + }, + "codersdk.ExternalAuthConfig": { + "type": "object", + "properties": { + "app_install_url": { + "type": "string" + }, + "app_installations_url": { + "type": "string" + }, + "auth_url": { + "type": "string" + }, + "client_id": { + "type": "string" + }, + "device_code_url": { + "type": "string" + }, + "device_flow": { + "type": "boolean" + }, + "display_icon": { + "description": "DisplayIcon is a URL to an icon to display in the UI.", + "type": "string" + }, + "display_name": { + "description": "DisplayName is shown in the UI to identify the auth config.", + "type": "string" + }, + "id": { + "description": "ID is a unique identifier for the auth config.\nIt defaults to `type` when not provided.", + "type": "string" + }, + "no_refresh": { + "type": "boolean" + }, + "regex": { + "description": "Regex allows API requesters to match an auth config by\na string (e.g. coder.com) instead of by it's type.\n\nGit clone makes use of this by parsing the URL from:\n'Username for \"https://github.com\":'\nAnd sending it to the Coder server to match against the Regex.", + "type": "string" + }, + "scopes": { + "type": "array", + "items": { + "type": "string" + } + }, + "token_url": { + "type": "string" + }, + "type": { + "description": "Type is the type of external auth config.", + "type": "string" + }, + "validate_url": { + "type": "string" + } + } + }, + "codersdk.ExternalAuthDevice": { + "type": "object", + "properties": { + "device_code": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "interval": { + "type": "integer" + }, + "user_code": { + "type": "string" + }, + "verification_uri": { + "type": "string" + } + } + }, + "codersdk.ExternalAuthLink": { + "type": "object", + "properties": { + "authenticated": { + "type": "boolean" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "expires": { + "type": "string", + "format": "date-time" + }, + "has_refresh_token": { + "type": "boolean" + }, + "provider_id": { + "type": "string" + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "validate_error": { + "type": "string" + } + } + }, + "codersdk.ExternalAuthUser": { + "type": "object", + "properties": { + "avatar_url": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "login": { + "type": "string" + }, + "name": { + "type": "string" + }, + "profile_url": { + "type": "string" + } + } + }, + "codersdk.Feature": { + "type": "object", + "properties": { + "actual": { + "type": "integer" + }, + "enabled": { + "type": "boolean" + }, + "entitlement": { + "$ref": "#/definitions/codersdk.Entitlement" + }, + "limit": { + "type": "integer" + } + } + }, + "codersdk.GenerateAPIKeyResponse": { + "type": "object", + "properties": { + "key": { + "type": "string" + } + } + }, + "codersdk.GetUsersResponse": { + "type": "object", + "properties": { + "count": { + "type": "integer" + }, + "users": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.User" + } + } + } + }, + "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.Group": { + "type": "object", + "properties": { + "avatar_url": { + "type": "string" + }, + "display_name": { + "type": "string" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "members": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.ReducedUser" + } + }, + "name": { + "type": "string" + }, + "organization_id": { + "type": "string", + "format": "uuid" + }, + "quota_allowance": { + "type": "integer" + }, + "source": { + "$ref": "#/definitions/codersdk.GroupSource" + }, + "total_member_count": { + "description": "How many members are in this group. Shows the total count,\neven if the user is not authorized to read group member details.\nMay be greater than `len(Group.Members)`.", + "type": "integer" + } + } + }, + "codersdk.GroupSource": { + "type": "string", + "enum": ["user", "oidc"], + "x-enum-varnames": ["GroupSourceUser", "GroupSourceOIDC"] + }, + "codersdk.Healthcheck": { + "type": "object", + "properties": { + "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.HealthcheckConfig": { + "type": "object", + "properties": { + "refresh": { + "type": "integer" + }, + "threshold_database": { + "type": "integer" + } + } + }, + "codersdk.InsightsReportInterval": { + "type": "string", + "enum": ["day", "week"], + "x-enum-varnames": [ + "InsightsReportIntervalDay", + "InsightsReportIntervalWeek" + ] + }, + "codersdk.IssueReconnectingPTYSignedTokenRequest": { + "type": "object", + "required": ["agentID", "url"], + "properties": { + "agentID": { + "type": "string", + "format": "uuid" + }, + "url": { + "description": "URL is the URL of the reconnecting-pty endpoint you are connecting to.", + "type": "string" + } + } + }, + "codersdk.IssueReconnectingPTYSignedTokenResponse": { + "type": "object", + "properties": { + "signed_token": { + "type": "string" + } + } + }, + "codersdk.JFrogXrayScan": { + "type": "object", + "properties": { + "agent_id": { + "type": "string", + "format": "uuid" + }, + "critical": { + "type": "integer" + }, + "high": { + "type": "integer" + }, + "medium": { + "type": "integer" + }, + "results_url": { + "type": "string" + }, + "workspace_id": { + "type": "string", + "format": "uuid" + } + } + }, + "codersdk.JobErrorCode": { + "type": "string", + "enum": ["REQUIRED_TEMPLATE_VARIABLES"], + "x-enum-varnames": ["RequiredTemplateVariables"] + }, + "codersdk.License": { + "type": "object", + "properties": { + "claims": { + "description": "Claims are the JWT claims asserted by the license. Here we use\na generic string map to ensure that all data from the server is\nparsed verbatim, not just the fields this version of Coder\nunderstands.", + "type": "object", + "additionalProperties": true + }, + "id": { + "type": "integer" + }, + "uploaded_at": { + "type": "string", + "format": "date-time" + }, + "uuid": { + "type": "string", + "format": "uuid" + } + } + }, + "codersdk.LinkConfig": { + "type": "object", + "properties": { + "icon": { + "type": "string", + "enum": ["bug", "chat", "docs"] + }, + "name": { + "type": "string" + }, + "target": { + "type": "string" + } + } + }, + "codersdk.LogLevel": { + "type": "string", + "enum": ["trace", "debug", "info", "warn", "error"], + "x-enum-varnames": [ + "LogLevelTrace", + "LogLevelDebug", + "LogLevelInfo", + "LogLevelWarn", + "LogLevelError" + ] + }, + "codersdk.LogSource": { + "type": "string", + "enum": ["provisioner_daemon", "provisioner"], + "x-enum-varnames": ["LogSourceProvisionerDaemon", "LogSourceProvisioner"] + }, + "codersdk.LoggingConfig": { + "type": "object", + "properties": { + "human": { + "type": "string" + }, + "json": { + "type": "string" + }, + "log_filter": { + "type": "array", + "items": { + "type": "string" + } + }, + "stackdriver": { + "type": "string" + } + } + }, + "codersdk.LoginType": { + "type": "string", + "enum": ["", "password", "github", "oidc", "token", "none"], + "x-enum-varnames": [ + "LoginTypeUnknown", + "LoginTypePassword", + "LoginTypeGithub", + "LoginTypeOIDC", + "LoginTypeToken", + "LoginTypeNone" + ] + }, + "codersdk.LoginWithPasswordRequest": { + "type": "object", + "required": ["email", "password"], + "properties": { + "email": { + "type": "string", + "format": "email" + }, + "password": { + "type": "string" + } + } + }, + "codersdk.LoginWithPasswordResponse": { + "type": "object", + "required": ["session_token"], + "properties": { + "session_token": { + "type": "string" + } + } + }, + "codersdk.MinimalOrganization": { + "type": "object", + "required": ["id"], + "properties": { + "display_name": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + } + } + }, + "codersdk.MinimalUser": { + "type": "object", + "required": ["id", "username"], + "properties": { + "avatar_url": { + "type": "string", + "format": "uri" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "username": { + "type": "string" + } + } + }, + "codersdk.NotificationMethodsResponse": { + "type": "object", + "properties": { + "available": { + "type": "array", + "items": { + "type": "string" + } + }, + "default": { + "type": "string" + } + } + }, + "codersdk.NotificationPreference": { + "type": "object", + "properties": { + "disabled": { + "type": "boolean" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "updated_at": { + "type": "string", + "format": "date-time" + } + } + }, + "codersdk.NotificationTemplate": { + "type": "object", + "properties": { + "actions": { + "type": "string" + }, + "body_template": { + "type": "string" + }, + "group": { + "type": "string" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "kind": { + "type": "string" + }, + "method": { + "type": "string" + }, + "name": { + "type": "string" + }, + "title_template": { + "type": "string" + } + } + }, + "codersdk.NotificationsConfig": { + "type": "object", + "properties": { + "dispatch_timeout": { + "description": "How long to wait while a notification is being sent before giving up.", + "type": "integer" + }, + "email": { + "description": "SMTP settings.", + "allOf": [ + { + "$ref": "#/definitions/codersdk.NotificationsEmailConfig" + } + ] + }, + "fetch_interval": { + "description": "How often to query the database for queued notifications.", + "type": "integer" + }, + "lease_count": { + "description": "How many notifications a notifier should lease per fetch interval.", + "type": "integer" + }, + "lease_period": { + "description": "How long a notifier should lease a message. This is effectively how long a notification is 'owned'\nby a notifier, and once this period expires it will be available for lease by another notifier. Leasing\nis important in order for multiple running notifiers to not pick the same messages to deliver concurrently.\nThis lease period will only expire if a notifier shuts down ungracefully; a dispatch of the notification\nreleases the lease.", + "type": "integer" + }, + "max_send_attempts": { + "description": "The upper limit of attempts to send a notification.", + "type": "integer" + }, + "method": { + "description": "Which delivery method to use (available options: 'smtp', 'webhook').", + "type": "string" + }, + "retry_interval": { + "description": "The minimum time between retries.", + "type": "integer" + }, + "sync_buffer_size": { + "description": "The notifications system buffers message updates in memory to ease pressure on the database.\nThis option controls how many updates are kept in memory. The lower this value the\nlower the change of state inconsistency in a non-graceful shutdown - but it also increases load on the\ndatabase. It is recommended to keep this option at its default value.", + "type": "integer" + }, + "sync_interval": { + "description": "The notifications system buffers message updates in memory to ease pressure on the database.\nThis option controls how often it synchronizes its state with the database. The shorter this value the\nlower the change of state inconsistency in a non-graceful shutdown - but it also increases load on the\ndatabase. It is recommended to keep this option at its default value.", + "type": "integer" + }, + "webhook": { + "description": "Webhook settings.", + "allOf": [ + { + "$ref": "#/definitions/codersdk.NotificationsWebhookConfig" + } + ] + } + } + }, + "codersdk.NotificationsEmailAuthConfig": { + "type": "object", + "properties": { + "identity": { + "description": "Identity for PLAIN auth.", + "type": "string" + }, + "password": { + "description": "Password for LOGIN/PLAIN auth.", + "type": "string" + }, + "password_file": { + "description": "File from which to load the password for LOGIN/PLAIN auth.", + "type": "string" + }, + "username": { + "description": "Username for LOGIN/PLAIN auth.", + "type": "string" + } + } + }, + "codersdk.NotificationsEmailConfig": { + "type": "object", + "properties": { + "auth": { + "description": "Authentication details.", + "allOf": [ + { + "$ref": "#/definitions/codersdk.NotificationsEmailAuthConfig" + } + ] + }, + "force_tls": { + "description": "ForceTLS causes a TLS connection to be attempted.", + "type": "boolean" + }, + "from": { + "description": "The sender's address.", + "type": "string" + }, + "hello": { + "description": "The hostname identifying the SMTP server.", + "type": "string" + }, + "smarthost": { + "description": "The intermediary SMTP host through which emails are sent (host:port).", + "allOf": [ + { + "$ref": "#/definitions/serpent.HostPort" + } + ] + }, + "tls": { + "description": "TLS details.", + "allOf": [ + { + "$ref": "#/definitions/codersdk.NotificationsEmailTLSConfig" + } + ] + } + } + }, + "codersdk.NotificationsEmailTLSConfig": { + "type": "object", + "properties": { + "ca_file": { + "description": "CAFile specifies the location of the CA certificate to use.", + "type": "string" + }, + "cert_file": { + "description": "CertFile specifies the location of the certificate to use.", + "type": "string" + }, + "insecure_skip_verify": { + "description": "InsecureSkipVerify skips target certificate validation.", + "type": "boolean" + }, + "key_file": { + "description": "KeyFile specifies the location of the key to use.", + "type": "string" + }, + "server_name": { + "description": "ServerName to verify the hostname for the targets.", + "type": "string" + }, + "start_tls": { + "description": "StartTLS attempts to upgrade plain connections to TLS.", + "type": "boolean" + } + } + }, + "codersdk.NotificationsSettings": { + "type": "object", + "properties": { + "notifier_paused": { + "type": "boolean" + } + } + }, + "codersdk.NotificationsWebhookConfig": { + "type": "object", + "properties": { + "endpoint": { + "description": "The URL to which the payload will be sent with an HTTP POST request.", + "allOf": [ + { + "$ref": "#/definitions/serpent.URL" + } + ] + } + } + }, + "codersdk.OAuth2AppEndpoints": { + "type": "object", + "properties": { + "authorization": { + "type": "string" + }, + "device_authorization": { + "description": "DeviceAuth is optional.", + "type": "string" + }, + "token": { + "type": "string" + } + } + }, + "codersdk.OAuth2Config": { + "type": "object", + "properties": { + "github": { + "$ref": "#/definitions/codersdk.OAuth2GithubConfig" + } + } + }, + "codersdk.OAuth2GithubConfig": { + "type": "object", + "properties": { + "allow_everyone": { + "type": "boolean" + }, + "allow_signups": { + "type": "boolean" + }, + "allowed_orgs": { + "type": "array", + "items": { + "type": "string" + } + }, + "allowed_teams": { + "type": "array", + "items": { + "type": "string" + } + }, + "client_id": { + "type": "string" + }, + "client_secret": { + "type": "string" + }, + "enterprise_base_url": { + "type": "string" + } + } + }, + "codersdk.OAuth2ProviderApp": { + "type": "object", + "properties": { + "callback_url": { + "type": "string" + }, + "endpoints": { + "description": "Endpoints are included in the app response for easier discovery. The OAuth2\nspec does not have a defined place to find these (for comparison, OIDC has\na '/.well-known/openid-configuration' endpoint).", + "allOf": [ + { + "$ref": "#/definitions/codersdk.OAuth2AppEndpoints" + } + ] + }, + "icon": { + "type": "string" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + } + } + }, + "codersdk.OAuth2ProviderAppSecret": { + "type": "object", + "properties": { + "client_secret_truncated": { + "type": "string" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "last_used_at": { + "type": "string" + } + } + }, + "codersdk.OAuth2ProviderAppSecretFull": { + "type": "object", + "properties": { + "client_secret_full": { + "type": "string" + }, + "id": { + "type": "string", + "format": "uuid" + } + } + }, + "codersdk.OAuthConversionResponse": { + "type": "object", + "properties": { + "expires_at": { + "type": "string", + "format": "date-time" + }, + "state_string": { + "type": "string" + }, + "to_type": { + "$ref": "#/definitions/codersdk.LoginType" + }, + "user_id": { + "type": "string", + "format": "uuid" + } + } + }, + "codersdk.OIDCAuthMethod": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "iconUrl": { + "type": "string" + }, + "signInText": { + "type": "string" + } + } + }, + "codersdk.OIDCConfig": { + "type": "object", + "properties": { + "allow_signups": { + "type": "boolean" + }, + "auth_url_params": { + "type": "object" + }, + "client_cert_file": { + "type": "string" + }, + "client_id": { + "type": "string" + }, + "client_key_file": { + "description": "ClientKeyFile \u0026 ClientCertFile are used in place of ClientSecret for PKI auth.", + "type": "string" + }, + "client_secret": { + "type": "string" + }, + "email_domain": { + "type": "array", + "items": { + "type": "string" + } + }, + "email_field": { + "type": "string" + }, + "group_allow_list": { + "type": "array", + "items": { + "type": "string" + } + }, + "group_auto_create": { + "type": "boolean" + }, + "group_mapping": { + "type": "object" + }, + "group_regex_filter": { + "$ref": "#/definitions/serpent.Regexp" + }, + "groups_field": { + "type": "string" + }, + "icon_url": { + "$ref": "#/definitions/serpent.URL" + }, + "ignore_email_verified": { + "type": "boolean" + }, + "ignore_user_info": { + "type": "boolean" + }, + "issuer_url": { + "type": "string" + }, + "name_field": { + "type": "string" + }, + "scopes": { + "type": "array", + "items": { + "type": "string" + } + }, + "sign_in_text": { + "type": "string" + }, + "signups_disabled_text": { + "type": "string" + }, + "skip_issuer_checks": { + "type": "boolean" + }, + "user_role_field": { + "type": "string" + }, + "user_role_mapping": { + "type": "object" + }, + "user_roles_default": { + "type": "array", + "items": { + "type": "string" + } + }, + "username_field": { + "type": "string" + } + } + }, + "codersdk.Organization": { + "type": "object", + "required": ["created_at", "id", "is_default", "updated_at"], + "properties": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "description": { + "type": "string" + }, + "display_name": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "is_default": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "updated_at": { + "type": "string", + "format": "date-time" + } + } + }, + "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.SlimRole" + } + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "user_id": { + "type": "string", + "format": "uuid" + } + } + }, + "codersdk.OrganizationMemberWithUserData": { + "type": "object", + "properties": { + "avatar_url": { + "type": "string" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "email": { + "type": "string" + }, + "global_roles": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.SlimRole" + } + }, + "name": { + "type": "string" + }, + "organization_id": { + "type": "string", + "format": "uuid" + }, + "roles": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.SlimRole" + } + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "user_id": { + "type": "string", + "format": "uuid" + }, + "username": { + "type": "string" + } + } + }, + "codersdk.PatchGroupRequest": { + "type": "object", + "properties": { + "add_users": { + "type": "array", + "items": { + "type": "string" + } + }, + "avatar_url": { + "type": "string" + }, + "display_name": { + "type": "string" + }, + "name": { + "type": "string" + }, + "quota_allowance": { + "type": "integer" + }, + "remove_users": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "codersdk.PatchTemplateVersionRequest": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "codersdk.PatchWorkspaceProxy": { + "type": "object", + "required": ["display_name", "icon", "id", "name"], + "properties": { + "display_name": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "regenerate_token": { + "type": "boolean" + } + } + }, + "codersdk.Permission": { + "type": "object", + "properties": { + "action": { + "$ref": "#/definitions/codersdk.RBACAction" + }, + "negate": { + "description": "Negate makes this a negative permission", + "type": "boolean" + }, + "resource_type": { + "$ref": "#/definitions/codersdk.RBACResource" + } + } + }, + "codersdk.PostOAuth2ProviderAppRequest": { + "type": "object", + "required": ["callback_url", "name"], + "properties": { + "callback_url": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "codersdk.PostWorkspaceUsageRequest": { + "type": "object", + "properties": { + "agent_id": { + "type": "string", + "format": "uuid" + }, + "app_name": { + "$ref": "#/definitions/codersdk.UsageAppName" + } + } + }, + "codersdk.PprofConfig": { + "type": "object", + "properties": { + "address": { + "$ref": "#/definitions/serpent.HostPort" + }, + "enable": { + "type": "boolean" + } + } + }, + "codersdk.PrometheusConfig": { + "type": "object", + "properties": { + "address": { + "$ref": "#/definitions/serpent.HostPort" + }, + "aggregate_agent_stats_by": { + "type": "array", + "items": { + "type": "string" + } + }, + "collect_agent_stats": { + "type": "boolean" + }, + "collect_db_metrics": { + "type": "boolean" + }, + "enable": { + "type": "boolean" + } + } + }, + "codersdk.ProvisionerConfig": { + "type": "object", + "properties": { + "daemon_poll_interval": { + "type": "integer" + }, + "daemon_poll_jitter": { + "type": "integer" + }, + "daemon_psk": { + "type": "string" + }, + "daemon_types": { + "type": "array", + "items": { + "type": "string" + } + }, + "daemons": { + "description": "Daemons is the number of built-in terraform provisioners.", + "type": "integer" + }, + "force_cancel_interval": { + "type": "integer" + } + } + }, + "codersdk.ProvisionerDaemon": { + "type": "object", + "properties": { + "api_version": { + "type": "string" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "last_seen_at": { + "type": "string", + "format": "date-time" + }, + "name": { + "type": "string" + }, + "organization_id": { + "type": "string", + "format": "uuid" + }, + "provisioners": { + "type": "array", + "items": { + "type": "string" + } + }, + "tags": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "version": { + "type": "string" + } + } + }, + "codersdk.ProvisionerJob": { + "type": "object", + "properties": { + "canceled_at": { + "type": "string", + "format": "date-time" + }, + "completed_at": { + "type": "string", + "format": "date-time" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "error": { + "type": "string" + }, + "error_code": { + "enum": ["REQUIRED_TEMPLATE_VARIABLES"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.JobErrorCode" + } + ] + }, + "file_id": { + "type": "string", + "format": "uuid" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "queue_position": { + "type": "integer" + }, + "queue_size": { + "type": "integer" + }, + "started_at": { + "type": "string", + "format": "date-time" + }, + "status": { + "enum": [ + "pending", + "running", + "succeeded", + "canceling", + "canceled", + "failed" + ], + "allOf": [ + { + "$ref": "#/definitions/codersdk.ProvisionerJobStatus" + } + ] + }, + "tags": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "worker_id": { + "type": "string", + "format": "uuid" + } + } + }, + "codersdk.ProvisionerJobLog": { + "type": "object", + "properties": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "id": { + "type": "integer" + }, + "log_level": { + "enum": ["trace", "debug", "info", "warn", "error"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.LogLevel" + } + ] + }, + "log_source": { + "$ref": "#/definitions/codersdk.LogSource" + }, + "output": { + "type": "string" + }, + "stage": { + "type": "string" + } + } + }, + "codersdk.ProvisionerJobStatus": { + "type": "string", + "enum": [ + "pending", + "running", + "succeeded", + "canceling", + "canceled", + "failed", + "unknown" + ], + "x-enum-varnames": [ + "ProvisionerJobPending", + "ProvisionerJobRunning", + "ProvisionerJobSucceeded", + "ProvisionerJobCanceling", + "ProvisionerJobCanceled", + "ProvisionerJobFailed", + "ProvisionerJobUnknown" + ] + }, + "codersdk.ProvisionerKey": { + "type": "object", + "properties": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "organization": { + "type": "string", + "format": "uuid" + }, + "tags": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "codersdk.ProvisionerLogLevel": { + "type": "string", + "enum": ["debug"], + "x-enum-varnames": ["ProvisionerLogLevelDebug"] + }, + "codersdk.ProvisionerStorageMethod": { + "type": "string", + "enum": ["file"], + "x-enum-varnames": ["ProvisionerStorageMethodFile"] + }, + "codersdk.ProxyHealthReport": { + "type": "object", + "properties": { + "errors": { + "description": "Errors are problems that prevent the workspace proxy from being healthy", + "type": "array", + "items": { + "type": "string" + } + }, + "warnings": { + "description": "Warnings do not prevent the workspace proxy from being healthy, but\nshould be addressed.", + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "codersdk.ProxyHealthStatus": { + "type": "string", + "enum": ["ok", "unreachable", "unhealthy", "unregistered"], + "x-enum-varnames": [ + "ProxyHealthy", + "ProxyUnreachable", + "ProxyUnhealthy", + "ProxyUnregistered" + ] + }, + "codersdk.PutExtendWorkspaceRequest": { + "type": "object", + "required": ["deadline"], + "properties": { + "deadline": { + "type": "string", + "format": "date-time" + } + } + }, + "codersdk.PutOAuth2ProviderAppRequest": { + "type": "object", + "required": ["callback_url", "name"], + "properties": { + "callback_url": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "codersdk.RBACAction": { + "type": "string", + "enum": [ + "application_connect", + "assign", + "create", + "delete", + "read", + "read_personal", + "ssh", + "update", + "update_personal", + "use", + "view_insights", + "start", + "stop" + ], + "x-enum-varnames": [ + "ActionApplicationConnect", + "ActionAssign", + "ActionCreate", + "ActionDelete", + "ActionRead", + "ActionReadPersonal", + "ActionSSH", + "ActionUpdate", + "ActionUpdatePersonal", + "ActionUse", + "ActionViewInsights", + "ActionWorkspaceStart", + "ActionWorkspaceStop" + ] + }, + "codersdk.RBACResource": { + "type": "string", + "enum": [ + "*", + "api_key", + "assign_org_role", + "assign_role", + "audit_log", + "debug_info", + "deployment_config", + "deployment_stats", + "file", + "group", + "group_member", + "license", + "notification_preference", + "notification_template", + "oauth2_app", + "oauth2_app_code_token", + "oauth2_app_secret", + "organization", + "organization_member", + "provisioner_daemon", + "provisioner_keys", + "replicas", + "system", + "tailnet_coordinator", + "template", + "user", + "workspace", + "workspace_dormant", + "workspace_proxy" + ], + "x-enum-varnames": [ + "ResourceWildcard", + "ResourceApiKey", + "ResourceAssignOrgRole", + "ResourceAssignRole", + "ResourceAuditLog", + "ResourceDebugInfo", + "ResourceDeploymentConfig", + "ResourceDeploymentStats", + "ResourceFile", + "ResourceGroup", + "ResourceGroupMember", + "ResourceLicense", + "ResourceNotificationPreference", + "ResourceNotificationTemplate", + "ResourceOauth2App", + "ResourceOauth2AppCodeToken", + "ResourceOauth2AppSecret", + "ResourceOrganization", + "ResourceOrganizationMember", + "ResourceProvisionerDaemon", + "ResourceProvisionerKeys", + "ResourceReplicas", + "ResourceSystem", + "ResourceTailnetCoordinator", + "ResourceTemplate", + "ResourceUser", + "ResourceWorkspace", + "ResourceWorkspaceDormant", + "ResourceWorkspaceProxy" + ] + }, + "codersdk.RateLimitConfig": { + "type": "object", + "properties": { + "api": { + "type": "integer" + }, + "disable_all": { + "type": "boolean" + } + } + }, + "codersdk.ReducedUser": { + "type": "object", + "required": ["created_at", "email", "id", "username"], + "properties": { + "avatar_url": { + "type": "string", + "format": "uri" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "email": { + "type": "string", + "format": "email" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "last_seen_at": { + "type": "string", + "format": "date-time" + }, + "login_type": { + "$ref": "#/definitions/codersdk.LoginType" + }, + "name": { + "type": "string" + }, + "status": { + "enum": ["active", "suspended"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.UserStatus" + } + ] + }, + "theme_preference": { + "type": "string" + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "username": { + "type": "string" + } + } + }, + "codersdk.Region": { + "type": "object", + "properties": { + "display_name": { + "type": "string" + }, + "healthy": { + "type": "boolean" + }, + "icon_url": { + "type": "string" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "path_app_url": { + "description": "PathAppURL is the URL to the base path for path apps. Optional\nunless wildcard_hostname is set.\nE.g. https://us.example.com", + "type": "string" + }, + "wildcard_hostname": { + "description": "WildcardHostname is the wildcard hostname for subdomain apps.\nE.g. *.us.example.com\nE.g. *--suffix.au.example.com\nOptional. Does not need to be on the same domain as PathAppURL.", + "type": "string" + } + } + }, + "codersdk.RegionsResponse-codersdk_Region": { + "type": "object", + "properties": { + "regions": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Region" + } + } + } + }, + "codersdk.RegionsResponse-codersdk_WorkspaceProxy": { + "type": "object", + "properties": { + "regions": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceProxy" + } + } + } + }, + "codersdk.Replica": { + "type": "object", + "properties": { + "created_at": { + "description": "CreatedAt is the timestamp when the replica was first seen.", + "type": "string", + "format": "date-time" + }, + "database_latency": { + "description": "DatabaseLatency is the latency in microseconds to the database.", + "type": "integer" + }, + "error": { + "description": "Error is the replica error.", + "type": "string" + }, + "hostname": { + "description": "Hostname is the hostname of the replica.", + "type": "string" + }, + "id": { + "description": "ID is the unique identifier for the replica.", + "type": "string", + "format": "uuid" + }, + "region_id": { + "description": "RegionID is the region of the replica.", + "type": "integer" + }, + "relay_address": { + "description": "RelayAddress is the accessible address to relay DERP connections.", + "type": "string" + } + } + }, + "codersdk.ResolveAutostartResponse": { + "type": "object", + "properties": { + "parameter_mismatch": { + "type": "boolean" + } + } + }, + "codersdk.ResourceType": { + "type": "string", + "enum": [ + "template", + "template_version", + "user", + "workspace", + "workspace_build", + "git_ssh_key", + "api_key", + "group", + "license", + "convert_login", + "health_settings", + "notifications_settings", + "workspace_proxy", + "organization", + "oauth2_provider_app", + "oauth2_provider_app_secret", + "custom_role" + ], + "x-enum-varnames": [ + "ResourceTypeTemplate", + "ResourceTypeTemplateVersion", + "ResourceTypeUser", + "ResourceTypeWorkspace", + "ResourceTypeWorkspaceBuild", + "ResourceTypeGitSSHKey", + "ResourceTypeAPIKey", + "ResourceTypeGroup", + "ResourceTypeLicense", + "ResourceTypeConvertLogin", + "ResourceTypeHealthSettings", + "ResourceTypeNotificationsSettings", + "ResourceTypeWorkspaceProxy", + "ResourceTypeOrganization", + "ResourceTypeOAuth2ProviderApp", + "ResourceTypeOAuth2ProviderAppSecret", + "ResourceTypeCustomRole" + ] + }, + "codersdk.Response": { + "type": "object", + "properties": { + "detail": { + "description": "Detail is a debug message that provides further insight into why the\naction failed. This information can be technical and a regular golang\nerr.Error() text.\n- \"database: too many open connections\"\n- \"stat: too many open files\"", + "type": "string" + }, + "message": { + "description": "Message is an actionable message that depicts actions the request took.\nThese messages should be fully formed sentences with proper punctuation.\nExamples:\n- \"A user has been created.\"\n- \"Failed to create a user.\"", + "type": "string" + }, + "validations": { + "description": "Validations are form field-specific friendly error messages. They will be\nshown on a form field in the UI. These can also be used to add additional\ncontext if there is a set of errors in the primary 'Message'.", + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.ValidationError" + } + } + } + }, + "codersdk.Role": { + "type": "object", + "properties": { + "display_name": { + "type": "string" + }, + "name": { + "type": "string" + }, + "organization_id": { + "type": "string", + "format": "uuid" + }, + "organization_permissions": { + "description": "OrganizationPermissions are specific for the organization in the field 'OrganizationID' above.", + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Permission" + } + }, + "site_permissions": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Permission" + } + }, + "user_permissions": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Permission" + } + } + } + }, + "codersdk.SSHConfig": { + "type": "object", + "properties": { + "deploymentName": { + "description": "DeploymentName is the config-ssh Hostname prefix", + "type": "string" + }, + "sshconfigOptions": { + "description": "SSHConfigOptions are additional options to add to the ssh config file.\nThis will override defaults.", + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "codersdk.SSHConfigResponse": { + "type": "object", + "properties": { + "hostname_prefix": { + "type": "string" + }, + "ssh_config_options": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "codersdk.SessionCountDeploymentStats": { + "type": "object", + "properties": { + "jetbrains": { + "type": "integer" + }, + "reconnecting_pty": { + "type": "integer" + }, + "ssh": { + "type": "integer" + }, + "vscode": { + "type": "integer" + } + } + }, + "codersdk.SessionLifetime": { + "type": "object", + "properties": { + "default_duration": { + "description": "DefaultDuration is for api keys, not tokens.", + "type": "integer" + }, + "disable_expiry_refresh": { + "description": "DisableExpiryRefresh will disable automatically refreshing api\nkeys when they are used from the api. This means the api key lifetime at\ncreation is the lifetime of the api key.", + "type": "boolean" + }, + "max_token_lifetime": { + "type": "integer" + } + } + }, + "codersdk.SlimRole": { + "type": "object", + "properties": { + "display_name": { + "type": "string" + }, + "name": { + "type": "string" + }, + "organization_id": { + "type": "string" + } + } + }, + "codersdk.SupportConfig": { + "type": "object", + "properties": { + "links": { + "$ref": "#/definitions/serpent.Struct-array_codersdk_LinkConfig" + } + } + }, + "codersdk.SwaggerConfig": { + "type": "object", + "properties": { + "enable": { + "type": "boolean" + } + } + }, + "codersdk.TLSConfig": { + "type": "object", + "properties": { + "address": { + "$ref": "#/definitions/serpent.HostPort" + }, + "allow_insecure_ciphers": { + "type": "boolean" + }, + "cert_file": { + "type": "array", + "items": { + "type": "string" + } + }, + "client_auth": { + "type": "string" + }, + "client_ca_file": { + "type": "string" + }, + "client_cert_file": { + "type": "string" + }, + "client_key_file": { + "type": "string" + }, + "enable": { + "type": "boolean" + }, + "key_file": { + "type": "array", + "items": { + "type": "string" + } + }, + "min_version": { + "type": "string" + }, + "redirect_http": { + "type": "boolean" + }, + "supported_ciphers": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "codersdk.TelemetryConfig": { + "type": "object", + "properties": { + "enable": { + "type": "boolean" + }, + "trace": { + "type": "boolean" + }, + "url": { + "$ref": "#/definitions/serpent.URL" + } + } + }, + "codersdk.Template": { + "type": "object", + "properties": { + "active_user_count": { + "description": "ActiveUserCount is set to -1 when loading.", + "type": "integer" + }, + "active_version_id": { + "type": "string", + "format": "uuid" + }, + "activity_bump_ms": { + "type": "integer" + }, + "allow_user_autostart": { + "description": "AllowUserAutostart and AllowUserAutostop are enterprise-only. Their\nvalues are only used if your license is entitled to use the advanced\ntemplate scheduling feature.", + "type": "boolean" + }, + "allow_user_autostop": { + "type": "boolean" + }, + "allow_user_cancel_workspace_jobs": { + "type": "boolean" + }, + "autostart_requirement": { + "$ref": "#/definitions/codersdk.TemplateAutostartRequirement" + }, + "autostop_requirement": { + "description": "AutostopRequirement and AutostartRequirement are enterprise features. Its\nvalue is only used if your license is entitled to use the advanced template\nscheduling feature.", + "allOf": [ + { + "$ref": "#/definitions/codersdk.TemplateAutostopRequirement" + } + ] + }, + "build_time_stats": { + "$ref": "#/definitions/codersdk.TemplateBuildTimeStats" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "created_by_id": { + "type": "string", + "format": "uuid" + }, + "created_by_name": { + "type": "string" + }, + "default_ttl_ms": { + "type": "integer" + }, + "deprecated": { + "type": "boolean" + }, + "deprecation_message": { + "type": "string" + }, + "description": { + "type": "string" + }, + "display_name": { + "type": "string" + }, + "failure_ttl_ms": { + "description": "FailureTTLMillis, TimeTilDormantMillis, and TimeTilDormantAutoDeleteMillis are enterprise-only. Their\nvalues are used if your license is entitled to use the advanced\ntemplate scheduling feature.", + "type": "integer" + }, + "icon": { + "type": "string" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "max_port_share_level": { + "$ref": "#/definitions/codersdk.WorkspaceAgentPortShareLevel" + }, + "name": { + "type": "string" + }, + "organization_display_name": { + "type": "string" + }, + "organization_icon": { + "type": "string" + }, + "organization_id": { + "type": "string", + "format": "uuid" + }, + "organization_name": { + "type": "string", + "format": "url" + }, + "provisioner": { + "type": "string", + "enum": ["terraform"] + }, + "require_active_version": { + "description": "RequireActiveVersion mandates that workspaces are built with the active\ntemplate version.", + "type": "boolean" + }, + "time_til_dormant_autodelete_ms": { + "type": "integer" + }, + "time_til_dormant_ms": { + "type": "integer" + }, + "updated_at": { + "type": "string", + "format": "date-time" + } + } + }, + "codersdk.TemplateAppUsage": { + "type": "object", + "properties": { + "display_name": { + "type": "string", + "example": "Visual Studio Code" + }, + "icon": { + "type": "string" + }, + "seconds": { + "type": "integer", + "example": 80500 + }, + "slug": { + "type": "string", + "example": "vscode" + }, + "template_ids": { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + } + }, + "times_used": { + "type": "integer", + "example": 2 + }, + "type": { + "allOf": [ + { + "$ref": "#/definitions/codersdk.TemplateAppsType" + } + ], + "example": "builtin" + } + } + }, + "codersdk.TemplateAppsType": { + "type": "string", + "enum": ["builtin", "app"], + "x-enum-varnames": ["TemplateAppsTypeBuiltin", "TemplateAppsTypeApp"] + }, + "codersdk.TemplateAutostartRequirement": { + "type": "object", + "properties": { + "days_of_week": { + "description": "DaysOfWeek is a list of days of the week in which autostart is allowed\nto happen. If no days are specified, autostart is not allowed.", + "type": "array", + "items": { + "type": "string", + "enum": [ + "monday", + "tuesday", + "wednesday", + "thursday", + "friday", + "saturday", + "sunday" + ] + } + } + } + }, + "codersdk.TemplateAutostopRequirement": { + "type": "object", + "properties": { + "days_of_week": { + "description": "DaysOfWeek is a list of days of the week on which restarts are required.\nRestarts happen within the user's quiet hours (in their configured\ntimezone). If no days are specified, restarts are not required. Weekdays\ncannot be specified twice.\n\nRestarts will only happen on weekdays in this list on weeks which line up\nwith Weeks.", + "type": "array", + "items": { + "type": "string", + "enum": [ + "monday", + "tuesday", + "wednesday", + "thursday", + "friday", + "saturday", + "sunday" + ] + } + }, + "weeks": { + "description": "Weeks is the number of weeks between required restarts. Weeks are synced\nacross all workspaces (and Coder deployments) using modulo math on a\nhardcoded epoch week of January 2nd, 2023 (the first Monday of 2023).\nValues of 0 or 1 indicate weekly restarts. Values of 2 indicate\nfortnightly restarts, etc.", + "type": "integer" + } + } + }, + "codersdk.TemplateBuildTimeStats": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/codersdk.TransitionStats" + } + }, + "codersdk.TemplateExample": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "markdown": { + "type": "string" + }, + "name": { + "type": "string" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "url": { + "type": "string" + } + } + }, + "codersdk.TemplateInsightsIntervalReport": { + "type": "object", + "properties": { + "active_users": { + "type": "integer", + "example": 14 + }, + "end_time": { + "type": "string", + "format": "date-time" + }, + "interval": { + "allOf": [ + { + "$ref": "#/definitions/codersdk.InsightsReportInterval" + } + ], + "example": "week" + }, + "start_time": { + "type": "string", + "format": "date-time" + }, + "template_ids": { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + } + } + } + }, + "codersdk.TemplateInsightsReport": { + "type": "object", + "properties": { + "active_users": { + "type": "integer", + "example": 22 + }, + "apps_usage": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.TemplateAppUsage" + } + }, + "end_time": { + "type": "string", + "format": "date-time" + }, + "parameters_usage": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.TemplateParameterUsage" + } + }, + "start_time": { + "type": "string", + "format": "date-time" + }, + "template_ids": { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + } + } + } + }, + "codersdk.TemplateInsightsResponse": { + "type": "object", + "properties": { + "interval_reports": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.TemplateInsightsIntervalReport" + } + }, + "report": { + "$ref": "#/definitions/codersdk.TemplateInsightsReport" + } + } + }, + "codersdk.TemplateParameterUsage": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "display_name": { + "type": "string" + }, + "name": { + "type": "string" + }, + "options": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.TemplateVersionParameterOption" + } + }, + "template_ids": { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + } + }, + "type": { + "type": "string" + }, + "values": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.TemplateParameterValue" + } + } + } + }, + "codersdk.TemplateParameterValue": { + "type": "object", + "properties": { + "count": { + "type": "integer" + }, + "value": { + "type": "string" + } + } + }, + "codersdk.TemplateRole": { + "type": "string", + "enum": ["admin", "use", ""], + "x-enum-varnames": [ + "TemplateRoleAdmin", + "TemplateRoleUse", + "TemplateRoleDeleted" + ] + }, + "codersdk.TemplateUser": { + "type": "object", + "required": ["created_at", "email", "id", "username"], + "properties": { + "avatar_url": { + "type": "string", + "format": "uri" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "email": { + "type": "string", + "format": "email" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "last_seen_at": { + "type": "string", + "format": "date-time" + }, + "login_type": { + "$ref": "#/definitions/codersdk.LoginType" + }, + "name": { + "type": "string" + }, + "organization_ids": { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + } + }, + "role": { + "enum": ["admin", "use"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.TemplateRole" + } + ] + }, + "roles": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.SlimRole" + } + }, + "status": { + "enum": ["active", "suspended"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.UserStatus" + } + ] + }, + "theme_preference": { + "type": "string" + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "username": { + "type": "string" + } + } + }, + "codersdk.TemplateVersion": { + "type": "object", + "properties": { + "archived": { + "type": "boolean" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "created_by": { + "$ref": "#/definitions/codersdk.MinimalUser" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "job": { + "$ref": "#/definitions/codersdk.ProvisionerJob" + }, + "message": { + "type": "string" + }, + "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" + }, + "warnings": { + "type": "array", + "items": { + "enum": ["DEPRECATED_PARAMETERS"], + "$ref": "#/definitions/codersdk.TemplateVersionWarning" + } + } + } + }, + "codersdk.TemplateVersionExternalAuth": { + "type": "object", + "properties": { + "authenticate_url": { + "type": "string" + }, + "authenticated": { + "type": "boolean" + }, + "display_icon": { + "type": "string" + }, + "display_name": { + "type": "string" + }, + "id": { + "type": "string" + }, + "optional": { + "type": "boolean" + }, + "type": { + "type": "string" + } + } + }, + "codersdk.TemplateVersionParameter": { + "type": "object", + "properties": { + "default_value": { + "type": "string" + }, + "description": { + "type": "string" + }, + "description_plaintext": { + "type": "string" + }, + "display_name": { + "type": "string" + }, + "ephemeral": { + "type": "boolean" + }, + "icon": { + "type": "string" + }, + "mutable": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "options": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.TemplateVersionParameterOption" + } + }, + "required": { + "type": "boolean" + }, + "type": { + "type": "string", + "enum": ["string", "number", "bool", "list(string)"] + }, + "validation_error": { + "type": "string" + }, + "validation_max": { + "type": "integer" + }, + "validation_min": { + "type": "integer" + }, + "validation_monotonic": { + "enum": ["increasing", "decreasing"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.ValidationMonotonicOrder" + } + ] + }, + "validation_regex": { + "type": "string" + } + } + }, + "codersdk.TemplateVersionParameterOption": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "codersdk.TemplateVersionVariable": { + "type": "object", + "properties": { + "default_value": { + "type": "string" + }, + "description": { + "type": "string" + }, + "name": { + "type": "string" + }, + "required": { + "type": "boolean" + }, + "sensitive": { + "type": "boolean" + }, + "type": { + "type": "string", + "enum": ["string", "number", "bool"] + }, + "value": { + "type": "string" + } + } + }, + "codersdk.TemplateVersionWarning": { + "type": "string", + "enum": ["UNSUPPORTED_WORKSPACES"], + "x-enum-varnames": ["TemplateVersionWarningUnsupportedWorkspaces"] + }, + "codersdk.TokenConfig": { + "type": "object", + "properties": { + "max_token_lifetime": { + "type": "integer" + } + } + }, + "codersdk.TraceConfig": { + "type": "object", + "properties": { + "capture_logs": { + "type": "boolean" + }, + "data_dog": { + "type": "boolean" + }, + "enable": { + "type": "boolean" + }, + "honeycomb_api_key": { + "type": "string" + } + } + }, + "codersdk.TransitionStats": { + "type": "object", + "properties": { + "p50": { + "type": "integer", + "example": 123 + }, + "p95": { + "type": "integer", + "example": 146 + } + } + }, + "codersdk.UpdateActiveTemplateVersion": { + "type": "object", + "required": ["id"], + "properties": { + "id": { + "type": "string", + "format": "uuid" + } + } + }, + "codersdk.UpdateAppearanceConfig": { + "type": "object", + "properties": { + "announcement_banners": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.BannerConfig" + } + }, + "application_name": { + "type": "string" + }, + "logo_url": { + "type": "string" + }, + "service_banner": { + "description": "Deprecated: ServiceBanner has been replaced by AnnouncementBanners.", + "allOf": [ + { + "$ref": "#/definitions/codersdk.BannerConfig" + } + ] + } + } + }, + "codersdk.UpdateCheckResponse": { + "type": "object", + "properties": { + "current": { + "description": "Current indicates whether the server version is the same as the latest.", + "type": "boolean" + }, + "url": { + "description": "URL to download the latest release of Coder.", + "type": "string" + }, + "version": { + "description": "Version is the semantic version for the latest release of Coder.", + "type": "string" + } + } + }, + "codersdk.UpdateOrganizationRequest": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "display_name": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "codersdk.UpdateRoles": { + "type": "object", + "properties": { + "roles": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "codersdk.UpdateTemplateACL": { + "type": "object", + "properties": { + "group_perms": { + "description": "GroupPerms should be a mapping of group id to role.", + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/codersdk.TemplateRole" + }, + "example": { + "8bd26b20-f3e8-48be-a903-46bb920cf671": "use", + "\u003cuser_id\u003e\u003e": "admin" + } + }, + "user_perms": { + "description": "UserPerms should be a mapping of user id to role. The user id must be the\nuuid of the user, not a username or email address.", + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/codersdk.TemplateRole" + }, + "example": { + "4df59e74-c027-470b-ab4d-cbba8963a5e9": "use", + "\u003cgroup_id\u003e": "admin" + } + } + } + }, + "codersdk.UpdateUserAppearanceSettingsRequest": { + "type": "object", + "required": ["theme_preference"], + "properties": { + "theme_preference": { + "type": "string" + } + } + }, + "codersdk.UpdateUserNotificationPreferences": { + "type": "object", + "properties": { + "template_disabled_map": { + "type": "object", + "additionalProperties": { + "type": "boolean" + } + } + } + }, + "codersdk.UpdateUserPasswordRequest": { + "type": "object", + "required": ["password"], + "properties": { + "old_password": { + "type": "string" + }, + "password": { + "type": "string" + } + } + }, + "codersdk.UpdateUserProfileRequest": { + "type": "object", + "required": ["username"], + "properties": { + "name": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "codersdk.UpdateUserQuietHoursScheduleRequest": { + "type": "object", + "required": ["schedule"], + "properties": { + "schedule": { + "description": "Schedule is a cron expression that defines when the user's quiet hours\nwindow is. Schedule must not be empty. For new users, the schedule is set\nto 2am in their browser or computer's timezone. The schedule denotes the\nbeginning of a 4 hour window where the workspace is allowed to\nautomatically stop or restart due to maintenance or template schedule.\n\nThe schedule must be daily with a single time, and should have a timezone\nspecified via a CRON_TZ prefix (otherwise UTC will be used).\n\nIf the schedule is empty, the user will be updated to use the default\nschedule.", + "type": "string" + } + } + }, + "codersdk.UpdateWorkspaceAutomaticUpdatesRequest": { + "type": "object", + "properties": { + "automatic_updates": { + "$ref": "#/definitions/codersdk.AutomaticUpdates" + } + } + }, + "codersdk.UpdateWorkspaceAutostartRequest": { + "type": "object", + "properties": { + "schedule": { + "description": "Schedule is expected to be of the form `CRON_TZ=\u003cIANA Timezone\u003e \u003cmin\u003e \u003chour\u003e * * \u003cdow\u003e`\nExample: `CRON_TZ=US/Central 30 9 * * 1-5` represents 0930 in the timezone US/Central\non weekdays (Mon-Fri). `CRON_TZ` defaults to UTC if not present.", + "type": "string" + } + } + }, + "codersdk.UpdateWorkspaceDormancy": { + "type": "object", + "properties": { + "dormant": { + "type": "boolean" + } + } + }, + "codersdk.UpdateWorkspaceRequest": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + } + }, + "codersdk.UpdateWorkspaceTTLRequest": { + "type": "object", + "properties": { + "ttl_ms": { + "type": "integer" + } + } + }, + "codersdk.UploadResponse": { + "type": "object", + "properties": { + "hash": { + "type": "string", + "format": "uuid" + } + } + }, + "codersdk.UpsertWorkspaceAgentPortShareRequest": { + "type": "object", + "properties": { + "agent_name": { + "type": "string" + }, + "port": { + "type": "integer" + }, + "protocol": { + "enum": ["http", "https"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.WorkspaceAgentPortShareProtocol" + } + ] + }, + "share_level": { + "enum": ["owner", "authenticated", "public"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.WorkspaceAgentPortShareLevel" + } + ] + } + } + }, + "codersdk.UsageAppName": { + "type": "string", + "enum": ["vscode", "jetbrains", "reconnecting-pty", "ssh"], + "x-enum-varnames": [ + "UsageAppNameVscode", + "UsageAppNameJetbrains", + "UsageAppNameReconnectingPty", + "UsageAppNameSSH" + ] + }, + "codersdk.User": { + "type": "object", + "required": ["created_at", "email", "id", "username"], + "properties": { + "avatar_url": { + "type": "string", + "format": "uri" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "email": { + "type": "string", + "format": "email" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "last_seen_at": { + "type": "string", + "format": "date-time" + }, + "login_type": { + "$ref": "#/definitions/codersdk.LoginType" + }, + "name": { + "type": "string" + }, + "organization_ids": { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + } + }, + "roles": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.SlimRole" + } + }, + "status": { + "enum": ["active", "suspended"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.UserStatus" + } + ] + }, + "theme_preference": { + "type": "string" + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "username": { + "type": "string" + } + } + }, + "codersdk.UserActivity": { + "type": "object", + "properties": { + "avatar_url": { + "type": "string", + "format": "uri" + }, + "seconds": { + "type": "integer", + "example": 80500 + }, + "template_ids": { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + } + }, + "user_id": { + "type": "string", + "format": "uuid" + }, + "username": { + "type": "string" + } + } + }, + "codersdk.UserActivityInsightsReport": { + "type": "object", + "properties": { + "end_time": { + "type": "string", + "format": "date-time" + }, + "start_time": { + "type": "string", + "format": "date-time" + }, + "template_ids": { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + } + }, + "users": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.UserActivity" + } + } + } + }, + "codersdk.UserActivityInsightsResponse": { + "type": "object", + "properties": { + "report": { + "$ref": "#/definitions/codersdk.UserActivityInsightsReport" + } + } + }, + "codersdk.UserLatency": { + "type": "object", + "properties": { + "avatar_url": { + "type": "string", + "format": "uri" + }, + "latency_ms": { + "$ref": "#/definitions/codersdk.ConnectionLatency" + }, + "template_ids": { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + } + }, + "user_id": { + "type": "string", + "format": "uuid" + }, + "username": { + "type": "string" + } + } + }, + "codersdk.UserLatencyInsightsReport": { + "type": "object", + "properties": { + "end_time": { + "type": "string", + "format": "date-time" + }, + "start_time": { + "type": "string", + "format": "date-time" + }, + "template_ids": { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + } + }, + "users": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.UserLatency" + } + } + } + }, + "codersdk.UserLatencyInsightsResponse": { + "type": "object", + "properties": { + "report": { + "$ref": "#/definitions/codersdk.UserLatencyInsightsReport" + } + } + }, + "codersdk.UserLoginType": { + "type": "object", + "properties": { + "login_type": { + "$ref": "#/definitions/codersdk.LoginType" + } + } + }, + "codersdk.UserParameter": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "codersdk.UserQuietHoursScheduleConfig": { + "type": "object", + "properties": { + "allow_user_custom": { + "type": "boolean" + }, + "default_schedule": { + "type": "string" + } + } + }, + "codersdk.UserQuietHoursScheduleResponse": { + "type": "object", + "properties": { + "next": { + "description": "Next is the next time that the quiet hours window will start.", + "type": "string", + "format": "date-time" + }, + "raw_schedule": { + "type": "string" + }, + "time": { + "description": "Time is the time of day that the quiet hours window starts in the given\nTimezone each day.", + "type": "string" + }, + "timezone": { + "description": "raw format from the cron expression, UTC if unspecified", + "type": "string" + }, + "user_can_set": { + "description": "UserCanSet is true if the user is allowed to set their own quiet hours\nschedule. If false, the user cannot set a custom schedule and the default\nschedule will always be used.", + "type": "boolean" + }, + "user_set": { + "description": "UserSet is true if the user has set their own quiet hours schedule. If\nfalse, the user is using the default schedule.", + "type": "boolean" + } + } + }, + "codersdk.UserStatus": { + "type": "string", + "enum": ["active", "dormant", "suspended"], + "x-enum-varnames": [ + "UserStatusActive", + "UserStatusDormant", + "UserStatusSuspended" + ] + }, + "codersdk.ValidationError": { + "type": "object", + "required": ["detail", "field"], + "properties": { + "detail": { + "type": "string" + }, + "field": { + "type": "string" + } + } + }, + "codersdk.ValidationMonotonicOrder": { + "type": "string", + "enum": ["increasing", "decreasing"], + "x-enum-varnames": [ + "MonotonicOrderIncreasing", + "MonotonicOrderDecreasing" + ] + }, + "codersdk.VariableValue": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "codersdk.Workspace": { + "type": "object", + "properties": { + "allow_renames": { + "type": "boolean" + }, + "automatic_updates": { + "enum": ["always", "never"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.AutomaticUpdates" + } + ] + }, + "autostart_schedule": { + "type": "string" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "deleting_at": { + "description": "DeletingAt indicates the time at which the workspace will be permanently deleted.\nA workspace is eligible for deletion if it is dormant (a non-nil dormant_at value)\nand a value has been specified for time_til_dormant_autodelete on its template.", + "type": "string", + "format": "date-time" + }, + "dormant_at": { + "description": "DormantAt being non-nil indicates a workspace that is dormant.\nA dormant workspace is no longer accessible must be activated.\nIt is subject to deletion if it breaches\nthe duration of the time_til_ field on its template.", + "type": "string", + "format": "date-time" + }, + "favorite": { + "type": "boolean" + }, + "health": { + "description": "Health shows the health of the workspace and information about\nwhat is causing an unhealthy status.", + "allOf": [ + { + "$ref": "#/definitions/codersdk.WorkspaceHealth" + } + ] + }, + "id": { + "type": "string", + "format": "uuid" + }, + "last_used_at": { + "type": "string", + "format": "date-time" + }, + "latest_build": { + "$ref": "#/definitions/codersdk.WorkspaceBuild" + }, + "name": { + "type": "string" + }, + "organization_id": { + "type": "string", + "format": "uuid" + }, + "organization_name": { + "type": "string" + }, + "outdated": { + "type": "boolean" + }, + "owner_avatar_url": { + "type": "string" + }, + "owner_id": { + "type": "string", + "format": "uuid" + }, + "owner_name": { + "type": "string" + }, + "template_active_version_id": { + "type": "string", + "format": "uuid" + }, + "template_allow_user_cancel_workspace_jobs": { + "type": "boolean" + }, + "template_display_name": { + "type": "string" + }, + "template_icon": { + "type": "string" + }, + "template_id": { + "type": "string", + "format": "uuid" + }, + "template_name": { + "type": "string" + }, + "template_require_active_version": { + "type": "boolean" + }, + "ttl_ms": { + "type": "integer" + }, + "updated_at": { + "type": "string", + "format": "date-time" + } + } + }, + "codersdk.WorkspaceAgent": { + "type": "object", + "properties": { + "api_version": { + "type": "string" + }, + "apps": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceApp" + } + }, + "architecture": { + "type": "string" + }, + "connection_timeout_seconds": { + "type": "integer" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "directory": { + "type": "string" + }, + "disconnected_at": { + "type": "string", + "format": "date-time" + }, + "display_apps": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.DisplayApp" + } + }, + "environment_variables": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "expanded_directory": { + "type": "string" + }, + "first_connected_at": { + "type": "string", + "format": "date-time" + }, + "health": { + "description": "Health reports the health of the agent.", + "allOf": [ + { + "$ref": "#/definitions/codersdk.WorkspaceAgentHealth" + } + ] + }, + "id": { + "type": "string", + "format": "uuid" + }, + "instance_id": { + "type": "string" + }, + "last_connected_at": { + "type": "string", + "format": "date-time" + }, + "latency": { + "description": "DERPLatency is mapped by region name (e.g. \"New York City\", \"Seattle\").", + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/codersdk.DERPRegion" + } + }, + "lifecycle_state": { + "$ref": "#/definitions/codersdk.WorkspaceAgentLifecycle" + }, + "log_sources": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceAgentLogSource" + } + }, + "logs_length": { + "type": "integer" + }, + "logs_overflowed": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "operating_system": { + "type": "string" + }, + "ready_at": { + "type": "string", + "format": "date-time" + }, + "resource_id": { + "type": "string", + "format": "uuid" + }, + "scripts": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceAgentScript" + } + }, + "started_at": { + "type": "string", + "format": "date-time" + }, + "startup_script_behavior": { + "description": "StartupScriptBehavior is a legacy field that is deprecated in favor\nof the `coder_script` resource. It's only referenced by old clients.\nDeprecated: Remove in the future!", + "allOf": [ + { + "$ref": "#/definitions/codersdk.WorkspaceAgentStartupScriptBehavior" + } + ] + }, + "status": { + "$ref": "#/definitions/codersdk.WorkspaceAgentStatus" + }, + "subsystems": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.AgentSubsystem" + } + }, + "troubleshooting_url": { + "type": "string" + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "version": { + "type": "string" + } + } + }, + "codersdk.WorkspaceAgentHealth": { + "type": "object", + "properties": { + "healthy": { + "description": "Healthy is true if the agent is healthy.", + "type": "boolean", + "example": false + }, + "reason": { + "description": "Reason is a human-readable explanation of the agent's health. It is empty if Healthy is true.", + "type": "string", + "example": "agent has lost connection" + } + } + }, + "codersdk.WorkspaceAgentLifecycle": { + "type": "string", + "enum": [ + "created", + "starting", + "start_timeout", + "start_error", + "ready", + "shutting_down", + "shutdown_timeout", + "shutdown_error", + "off" + ], + "x-enum-varnames": [ + "WorkspaceAgentLifecycleCreated", + "WorkspaceAgentLifecycleStarting", + "WorkspaceAgentLifecycleStartTimeout", + "WorkspaceAgentLifecycleStartError", + "WorkspaceAgentLifecycleReady", + "WorkspaceAgentLifecycleShuttingDown", + "WorkspaceAgentLifecycleShutdownTimeout", + "WorkspaceAgentLifecycleShutdownError", + "WorkspaceAgentLifecycleOff" + ] + }, + "codersdk.WorkspaceAgentListeningPort": { + "type": "object", + "properties": { + "network": { + "description": "only \"tcp\" at the moment", + "type": "string" + }, + "port": { + "type": "integer" + }, + "process_name": { + "description": "may be empty", + "type": "string" + } + } + }, + "codersdk.WorkspaceAgentListeningPortsResponse": { + "type": "object", + "properties": { + "ports": { + "description": "If there are no ports in the list, nothing should be displayed in the UI.\nThere must not be a \"no ports available\" message or anything similar, as\nthere will always be no ports displayed on platforms where our port\ndetection logic is unsupported.", + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceAgentListeningPort" + } + } + } + }, + "codersdk.WorkspaceAgentLog": { + "type": "object", + "properties": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "id": { + "type": "integer" + }, + "level": { + "$ref": "#/definitions/codersdk.LogLevel" + }, + "output": { + "type": "string" + }, + "source_id": { + "type": "string", + "format": "uuid" + } + } + }, + "codersdk.WorkspaceAgentLogSource": { + "type": "object", + "properties": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "display_name": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "workspace_agent_id": { + "type": "string", + "format": "uuid" + } + } + }, + "codersdk.WorkspaceAgentPortShare": { + "type": "object", + "properties": { + "agent_name": { + "type": "string" + }, + "port": { + "type": "integer" + }, + "protocol": { + "enum": ["http", "https"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.WorkspaceAgentPortShareProtocol" + } + ] + }, + "share_level": { + "enum": ["owner", "authenticated", "public"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.WorkspaceAgentPortShareLevel" + } + ] + }, + "workspace_id": { + "type": "string", + "format": "uuid" + } + } + }, + "codersdk.WorkspaceAgentPortShareLevel": { + "type": "string", + "enum": ["owner", "authenticated", "public"], + "x-enum-varnames": [ + "WorkspaceAgentPortShareLevelOwner", + "WorkspaceAgentPortShareLevelAuthenticated", + "WorkspaceAgentPortShareLevelPublic" + ] + }, + "codersdk.WorkspaceAgentPortShareProtocol": { + "type": "string", + "enum": ["http", "https"], + "x-enum-varnames": [ + "WorkspaceAgentPortShareProtocolHTTP", + "WorkspaceAgentPortShareProtocolHTTPS" + ] + }, + "codersdk.WorkspaceAgentPortShares": { + "type": "object", + "properties": { + "shares": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceAgentPortShare" + } + } + } + }, + "codersdk.WorkspaceAgentScript": { + "type": "object", + "properties": { + "cron": { + "type": "string" + }, + "log_path": { + "type": "string" + }, + "log_source_id": { + "type": "string", + "format": "uuid" + }, + "run_on_start": { + "type": "boolean" + }, + "run_on_stop": { + "type": "boolean" + }, + "script": { + "type": "string" + }, + "start_blocks_login": { + "type": "boolean" + }, + "timeout": { + "type": "integer" + } + } + }, + "codersdk.WorkspaceAgentStartupScriptBehavior": { + "type": "string", + "enum": ["blocking", "non-blocking"], + "x-enum-varnames": [ + "WorkspaceAgentStartupScriptBehaviorBlocking", + "WorkspaceAgentStartupScriptBehaviorNonBlocking" + ] + }, + "codersdk.WorkspaceAgentStatus": { + "type": "string", + "enum": ["connecting", "connected", "disconnected", "timeout"], + "x-enum-varnames": [ + "WorkspaceAgentConnecting", + "WorkspaceAgentConnected", + "WorkspaceAgentDisconnected", + "WorkspaceAgentTimeout" + ] + }, + "codersdk.WorkspaceApp": { + "type": "object", + "properties": { + "command": { + "type": "string" + }, + "display_name": { + "description": "DisplayName is a friendly name for the app.", + "type": "string" + }, + "external": { + "description": "External specifies whether the URL should be opened externally on\nthe client or not.", + "type": "boolean" + }, + "health": { + "$ref": "#/definitions/codersdk.WorkspaceAppHealth" + }, + "healthcheck": { + "description": "Healthcheck specifies the configuration for checking app health.", + "allOf": [ + { + "$ref": "#/definitions/codersdk.Healthcheck" + } + ] + }, + "icon": { + "description": "Icon is a relative path or external URL that specifies\nan icon to be displayed in the dashboard.", + "type": "string" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "sharing_level": { + "enum": ["owner", "authenticated", "public"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.WorkspaceAppSharingLevel" + } + ] + }, + "slug": { + "description": "Slug is a unique identifier within the agent.", + "type": "string" + }, + "subdomain": { + "description": "Subdomain denotes whether the app should be accessed via a path on the\n`coder server` or via a hostname-based dev URL. If this is set to true\nand there is no app wildcard configured on the server, the app will not\nbe accessible in the UI.", + "type": "boolean" + }, + "subdomain_name": { + "description": "SubdomainName is the application domain exposed on the `coder server`.", + "type": "string" + }, + "url": { + "description": "URL is the address being proxied to inside the workspace.\nIf external is specified, this will be opened on the client.", + "type": "string" + } + } + }, + "codersdk.WorkspaceAppHealth": { + "type": "string", + "enum": ["disabled", "initializing", "healthy", "unhealthy"], + "x-enum-varnames": [ + "WorkspaceAppHealthDisabled", + "WorkspaceAppHealthInitializing", + "WorkspaceAppHealthHealthy", + "WorkspaceAppHealthUnhealthy" + ] + }, + "codersdk.WorkspaceAppSharingLevel": { + "type": "string", + "enum": ["owner", "authenticated", "public"], + "x-enum-varnames": [ + "WorkspaceAppSharingLevelOwner", + "WorkspaceAppSharingLevelAuthenticated", + "WorkspaceAppSharingLevelPublic" + ] + }, + "codersdk.WorkspaceBuild": { + "type": "object", + "properties": { + "build_number": { + "type": "integer" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "daily_cost": { + "type": "integer" + }, + "deadline": { + "type": "string", + "format": "date-time" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "initiator_id": { + "type": "string", + "format": "uuid" + }, + "initiator_name": { + "type": "string" + }, + "job": { + "$ref": "#/definitions/codersdk.ProvisionerJob" + }, + "max_deadline": { + "type": "string", + "format": "date-time" + }, + "reason": { + "enum": ["initiator", "autostart", "autostop"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.BuildReason" + } + ] + }, + "resources": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceResource" + } + }, + "status": { + "enum": [ + "pending", + "starting", + "running", + "stopping", + "stopped", + "failed", + "canceling", + "canceled", + "deleting", + "deleted" + ], + "allOf": [ + { + "$ref": "#/definitions/codersdk.WorkspaceStatus" + } + ] + }, + "template_version_id": { + "type": "string", + "format": "uuid" + }, + "template_version_name": { + "type": "string" + }, + "transition": { + "enum": ["start", "stop", "delete"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.WorkspaceTransition" + } + ] + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "workspace_id": { + "type": "string", + "format": "uuid" + }, + "workspace_name": { + "type": "string" + }, + "workspace_owner_avatar_url": { + "type": "string" + }, + "workspace_owner_id": { + "type": "string", + "format": "uuid" + }, + "workspace_owner_name": { + "type": "string" + } + } + }, + "codersdk.WorkspaceBuildParameter": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "codersdk.WorkspaceConnectionLatencyMS": { + "type": "object", + "properties": { + "p50": { + "type": "number" + }, + "p95": { + "type": "number" + } + } + }, + "codersdk.WorkspaceDeploymentStats": { + "type": "object", + "properties": { + "building": { + "type": "integer" + }, + "connection_latency_ms": { + "$ref": "#/definitions/codersdk.WorkspaceConnectionLatencyMS" + }, + "failed": { + "type": "integer" + }, + "pending": { + "type": "integer" + }, + "running": { + "type": "integer" + }, + "rx_bytes": { + "type": "integer" + }, + "stopped": { + "type": "integer" + }, + "tx_bytes": { + "type": "integer" + } + } + }, + "codersdk.WorkspaceHealth": { + "type": "object", + "properties": { + "failing_agents": { + "description": "FailingAgents lists the IDs of the agents that are failing, if any.", + "type": "array", + "items": { + "type": "string", + "format": "uuid" + } + }, + "healthy": { + "description": "Healthy is true if the workspace is healthy.", + "type": "boolean", + "example": false + } + } + }, + "codersdk.WorkspaceProxy": { + "type": "object", + "properties": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "deleted": { + "type": "boolean" + }, + "derp_enabled": { + "type": "boolean" + }, + "derp_only": { + "type": "boolean" + }, + "display_name": { + "type": "string" + }, + "healthy": { + "type": "boolean" + }, + "icon_url": { + "type": "string" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "path_app_url": { + "description": "PathAppURL is the URL to the base path for path apps. Optional\nunless wildcard_hostname is set.\nE.g. https://us.example.com", + "type": "string" + }, + "status": { + "description": "Status is the latest status check of the proxy. This will be empty for deleted\nproxies. This value can be used to determine if a workspace proxy is healthy\nand ready to use.", + "allOf": [ + { + "$ref": "#/definitions/codersdk.WorkspaceProxyStatus" + } + ] + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "version": { + "type": "string" + }, + "wildcard_hostname": { + "description": "WildcardHostname is the wildcard hostname for subdomain apps.\nE.g. *.us.example.com\nE.g. *--suffix.au.example.com\nOptional. Does not need to be on the same domain as PathAppURL.", + "type": "string" + } + } + }, + "codersdk.WorkspaceProxyStatus": { + "type": "object", + "properties": { + "checked_at": { + "type": "string", + "format": "date-time" + }, + "report": { + "description": "Report provides more information about the health of the workspace proxy.", + "allOf": [ + { + "$ref": "#/definitions/codersdk.ProxyHealthReport" + } + ] + }, + "status": { + "$ref": "#/definitions/codersdk.ProxyHealthStatus" + } + } + }, + "codersdk.WorkspaceQuota": { + "type": "object", + "properties": { + "budget": { + "type": "integer" + }, + "credits_consumed": { + "type": "integer" + } + } + }, + "codersdk.WorkspaceResource": { + "type": "object", + "properties": { + "agents": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceAgent" + } + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "daily_cost": { + "type": "integer" + }, + "hide": { + "type": "boolean" + }, + "icon": { + "type": "string" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "job_id": { + "type": "string", + "format": "uuid" + }, + "metadata": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceResourceMetadata" + } + }, + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "workspace_transition": { + "enum": ["start", "stop", "delete"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.WorkspaceTransition" + } + ] + } + } + }, + "codersdk.WorkspaceResourceMetadata": { + "type": "object", + "properties": { + "key": { + "type": "string" + }, + "sensitive": { + "type": "boolean" + }, + "value": { + "type": "string" + } + } + }, + "codersdk.WorkspaceStatus": { + "type": "string", + "enum": [ + "pending", + "starting", + "running", + "stopping", + "stopped", + "failed", + "canceling", + "canceled", + "deleting", + "deleted" + ], + "x-enum-varnames": [ + "WorkspaceStatusPending", + "WorkspaceStatusStarting", + "WorkspaceStatusRunning", + "WorkspaceStatusStopping", + "WorkspaceStatusStopped", + "WorkspaceStatusFailed", + "WorkspaceStatusCanceling", + "WorkspaceStatusCanceled", + "WorkspaceStatusDeleting", + "WorkspaceStatusDeleted" + ] + }, + "codersdk.WorkspaceTransition": { + "type": "string", + "enum": ["start", "stop", "delete"], + "x-enum-varnames": [ + "WorkspaceTransitionStart", + "WorkspaceTransitionStop", + "WorkspaceTransitionDelete" + ] + }, + "codersdk.WorkspacesResponse": { + "type": "object", + "properties": { + "count": { + "type": "integer" + }, + "workspaces": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Workspace" + } + } + } + }, + "derp.BytesSentRecv": { + "type": "object", + "properties": { + "key": { + "description": "Key is the public key of the client which sent/received these bytes.", + "allOf": [ + { + "$ref": "#/definitions/key.NodePublic" + } + ] + }, + "recv": { + "type": "integer" + }, + "sent": { + "type": "integer" + } + } + }, + "derp.ServerInfoMessage": { + "type": "object", + "properties": { + "tokenBucketBytesBurst": { + "description": "TokenBucketBytesBurst is how many bytes the server will\nallow to burst, temporarily violating\nTokenBucketBytesPerSecond.\n\nZero means unspecified. There might be a limit, but the\nclient need not try to respect it.", + "type": "integer" + }, + "tokenBucketBytesPerSecond": { + "description": "TokenBucketBytesPerSecond is how many bytes per second the\nserver says it will accept, including all framing bytes.\n\nZero means unspecified. There might be a limit, but the\nclient need not try to respect it.", + "type": "integer" + } + } + }, + "health.Code": { + "type": "string", + "enum": [ + "EUNKNOWN", + "EWP01", + "EWP02", + "EWP04", + "EDB01", + "EDB02", + "EWS01", + "EWS02", + "EWS03", + "EACS01", + "EACS02", + "EACS03", + "EACS04", + "EDERP01", + "EDERP02", + "EPD01", + "EPD02", + "EPD03" + ], + "x-enum-varnames": [ + "CodeUnknown", + "CodeProxyUpdate", + "CodeProxyFetch", + "CodeProxyUnhealthy", + "CodeDatabasePingFailed", + "CodeDatabasePingSlow", + "CodeWebsocketDial", + "CodeWebsocketEcho", + "CodeWebsocketMsg", + "CodeAccessURLNotSet", + "CodeAccessURLInvalid", + "CodeAccessURLFetch", + "CodeAccessURLNotOK", + "CodeDERPNodeUsesWebsocket", + "CodeDERPOneNodeUnhealthy", + "CodeProvisionerDaemonsNoProvisionerDaemons", + "CodeProvisionerDaemonVersionMismatch", + "CodeProvisionerDaemonAPIMajorVersionDeprecated" + ] + }, + "health.Message": { + "type": "object", + "properties": { + "code": { + "$ref": "#/definitions/health.Code" + }, + "message": { + "type": "string" + } + } + }, + "health.Severity": { + "type": "string", + "enum": ["ok", "warning", "error"], + "x-enum-varnames": ["SeverityOK", "SeverityWarning", "SeverityError"] + }, + "healthsdk.AccessURLReport": { + "type": "object", + "properties": { + "access_url": { + "type": "string" + }, + "dismissed": { + "type": "boolean" + }, + "error": { + "type": "string" + }, + "healthy": { + "description": "Healthy is deprecated and left for backward compatibility purposes, use `Severity` instead.", + "type": "boolean" + }, + "healthz_response": { + "type": "string" + }, + "reachable": { + "type": "boolean" + }, + "severity": { + "enum": ["ok", "warning", "error"], + "allOf": [ + { + "$ref": "#/definitions/health.Severity" + } + ] + }, + "status_code": { + "type": "integer" + }, + "warnings": { + "type": "array", + "items": { + "$ref": "#/definitions/health.Message" + } + } + } + }, + "healthsdk.DERPHealthReport": { + "type": "object", + "properties": { + "dismissed": { + "type": "boolean" + }, + "error": { + "type": "string" + }, + "healthy": { + "description": "Healthy is deprecated and left for backward compatibility purposes, use `Severity` instead.", + "type": "boolean" + }, + "netcheck": { + "$ref": "#/definitions/netcheck.Report" + }, + "netcheck_err": { + "type": "string" + }, + "netcheck_logs": { + "type": "array", + "items": { + "type": "string" + } + }, + "regions": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/healthsdk.DERPRegionReport" + } + }, + "severity": { + "enum": ["ok", "warning", "error"], + "allOf": [ + { + "$ref": "#/definitions/health.Severity" + } + ] + }, + "warnings": { + "type": "array", + "items": { + "$ref": "#/definitions/health.Message" + } + } + } + }, + "healthsdk.DERPNodeReport": { + "type": "object", + "properties": { + "can_exchange_messages": { + "type": "boolean" + }, + "client_errs": { + "type": "array", + "items": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "client_logs": { + "type": "array", + "items": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "error": { + "type": "string" + }, + "healthy": { + "description": "Healthy is deprecated and left for backward compatibility purposes, use `Severity` instead.", + "type": "boolean" + }, + "node": { + "$ref": "#/definitions/tailcfg.DERPNode" + }, + "node_info": { + "$ref": "#/definitions/derp.ServerInfoMessage" + }, + "round_trip_ping": { + "type": "string" + }, + "round_trip_ping_ms": { + "type": "integer" + }, + "severity": { + "enum": ["ok", "warning", "error"], + "allOf": [ + { + "$ref": "#/definitions/health.Severity" + } + ] + }, + "stun": { + "$ref": "#/definitions/healthsdk.STUNReport" + }, + "uses_websocket": { + "type": "boolean" + }, + "warnings": { + "type": "array", + "items": { + "$ref": "#/definitions/health.Message" + } + } + } + }, + "healthsdk.DERPRegionReport": { + "type": "object", + "properties": { + "error": { + "type": "string" + }, + "healthy": { + "description": "Healthy is deprecated and left for backward compatibility purposes, use `Severity` instead.", + "type": "boolean" + }, + "node_reports": { + "type": "array", + "items": { + "$ref": "#/definitions/healthsdk.DERPNodeReport" + } + }, + "region": { + "$ref": "#/definitions/tailcfg.DERPRegion" + }, + "severity": { + "enum": ["ok", "warning", "error"], + "allOf": [ + { + "$ref": "#/definitions/health.Severity" + } + ] + }, + "warnings": { + "type": "array", + "items": { + "$ref": "#/definitions/health.Message" + } + } + } + }, + "healthsdk.DatabaseReport": { + "type": "object", + "properties": { + "dismissed": { + "type": "boolean" + }, + "error": { + "type": "string" + }, + "healthy": { + "description": "Healthy is deprecated and left for backward compatibility purposes, use `Severity` instead.", + "type": "boolean" + }, + "latency": { + "type": "string" + }, + "latency_ms": { + "type": "integer" + }, + "reachable": { + "type": "boolean" + }, + "severity": { + "enum": ["ok", "warning", "error"], + "allOf": [ + { + "$ref": "#/definitions/health.Severity" + } + ] + }, + "threshold_ms": { + "type": "integer" + }, + "warnings": { + "type": "array", + "items": { + "$ref": "#/definitions/health.Message" + } + } + } + }, + "healthsdk.HealthSection": { + "type": "string", + "enum": [ + "DERP", + "AccessURL", + "Websocket", + "Database", + "WorkspaceProxy", + "ProvisionerDaemons" + ], + "x-enum-varnames": [ + "HealthSectionDERP", + "HealthSectionAccessURL", + "HealthSectionWebsocket", + "HealthSectionDatabase", + "HealthSectionWorkspaceProxy", + "HealthSectionProvisionerDaemons" + ] + }, + "healthsdk.HealthSettings": { + "type": "object", + "properties": { + "dismissed_healthchecks": { + "type": "array", + "items": { + "$ref": "#/definitions/healthsdk.HealthSection" + } + } + } + }, + "healthsdk.HealthcheckReport": { + "type": "object", + "properties": { + "access_url": { + "$ref": "#/definitions/healthsdk.AccessURLReport" + }, + "coder_version": { + "description": "The Coder version of the server that the report was generated on.", + "type": "string" + }, + "database": { + "$ref": "#/definitions/healthsdk.DatabaseReport" + }, + "derp": { + "$ref": "#/definitions/healthsdk.DERPHealthReport" + }, + "healthy": { + "description": "Healthy is true if the report returns no errors.\nDeprecated: use `Severity` instead", + "type": "boolean" + }, + "provisioner_daemons": { + "$ref": "#/definitions/healthsdk.ProvisionerDaemonsReport" + }, + "severity": { + "description": "Severity indicates the status of Coder health.", + "enum": ["ok", "warning", "error"], + "allOf": [ + { + "$ref": "#/definitions/health.Severity" + } + ] + }, + "time": { + "description": "Time is the time the report was generated at.", + "type": "string", + "format": "date-time" + }, + "websocket": { + "$ref": "#/definitions/healthsdk.WebsocketReport" + }, + "workspace_proxy": { + "$ref": "#/definitions/healthsdk.WorkspaceProxyReport" + } + } + }, + "healthsdk.ProvisionerDaemonsReport": { + "type": "object", + "properties": { + "dismissed": { + "type": "boolean" + }, + "error": { + "type": "string" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/healthsdk.ProvisionerDaemonsReportItem" + } + }, + "severity": { + "enum": ["ok", "warning", "error"], + "allOf": [ + { + "$ref": "#/definitions/health.Severity" + } + ] + }, + "warnings": { + "type": "array", + "items": { + "$ref": "#/definitions/health.Message" + } + } + } + }, + "healthsdk.ProvisionerDaemonsReportItem": { + "type": "object", + "properties": { + "provisioner_daemon": { + "$ref": "#/definitions/codersdk.ProvisionerDaemon" + }, + "warnings": { + "type": "array", + "items": { + "$ref": "#/definitions/health.Message" + } + } + } + }, + "healthsdk.STUNReport": { + "type": "object", + "properties": { + "canSTUN": { + "type": "boolean" + }, + "enabled": { + "type": "boolean" + }, + "error": { + "type": "string" + } + } + }, + "healthsdk.UpdateHealthSettings": { + "type": "object", + "properties": { + "dismissed_healthchecks": { + "type": "array", + "items": { + "$ref": "#/definitions/healthsdk.HealthSection" + } + } + } + }, + "healthsdk.WebsocketReport": { + "type": "object", + "properties": { + "body": { + "type": "string" + }, + "code": { + "type": "integer" + }, + "dismissed": { + "type": "boolean" + }, + "error": { + "type": "string" + }, + "healthy": { + "description": "Healthy is deprecated and left for backward compatibility purposes, use `Severity` instead.", + "type": "boolean" + }, + "severity": { + "enum": ["ok", "warning", "error"], + "allOf": [ + { + "$ref": "#/definitions/health.Severity" + } + ] + }, + "warnings": { + "type": "array", + "items": { + "$ref": "#/definitions/health.Message" + } + } + } + }, + "healthsdk.WorkspaceProxyReport": { + "type": "object", + "properties": { + "dismissed": { + "type": "boolean" + }, + "error": { + "type": "string" + }, + "healthy": { + "description": "Healthy is deprecated and left for backward compatibility purposes, use `Severity` instead.", + "type": "boolean" + }, + "severity": { + "enum": ["ok", "warning", "error"], + "allOf": [ + { + "$ref": "#/definitions/health.Severity" + } + ] + }, + "warnings": { + "type": "array", + "items": { + "$ref": "#/definitions/health.Message" + } + }, + "workspace_proxies": { + "$ref": "#/definitions/codersdk.RegionsResponse-codersdk_WorkspaceProxy" + } + } + }, + "key.NodePublic": { + "type": "object" + }, + "netcheck.Report": { + "type": "object", + "properties": { + "captivePortal": { + "description": "CaptivePortal is set when we think there's a captive portal that is\nintercepting HTTP traffic.", + "type": "string" + }, + "globalV4": { + "description": "ip:port of global IPv4", + "type": "string" + }, + "globalV6": { + "description": "[ip]:port of global IPv6", + "type": "string" + }, + "hairPinning": { + "description": "HairPinning is whether the router supports communicating\nbetween two local devices through the NATted public IP address\n(on IPv4).", + "type": "string" + }, + "icmpv4": { + "description": "an ICMPv4 round trip completed", + "type": "boolean" + }, + "ipv4": { + "description": "an IPv4 STUN round trip completed", + "type": "boolean" + }, + "ipv4CanSend": { + "description": "an IPv4 packet was able to be sent", + "type": "boolean" + }, + "ipv6": { + "description": "an IPv6 STUN round trip completed", + "type": "boolean" + }, + "ipv6CanSend": { + "description": "an IPv6 packet was able to be sent", + "type": "boolean" + }, + "mappingVariesByDestIP": { + "description": "MappingVariesByDestIP is whether STUN results depend which\nSTUN server you're talking to (on IPv4).", + "type": "string" + }, + "oshasIPv6": { + "description": "could bind a socket to ::1", + "type": "boolean" + }, + "pcp": { + "description": "PCP is whether PCP appears present on the LAN.\nEmpty means not checked.", + "type": "string" + }, + "pmp": { + "description": "PMP is whether NAT-PMP appears present on the LAN.\nEmpty means not checked.", + "type": "string" + }, + "preferredDERP": { + "description": "or 0 for unknown", + "type": "integer" + }, + "regionLatency": { + "description": "keyed by DERP Region ID", + "type": "object", + "additionalProperties": { + "type": "integer" + } + }, + "regionV4Latency": { + "description": "keyed by DERP Region ID", + "type": "object", + "additionalProperties": { + "type": "integer" + } + }, + "regionV6Latency": { + "description": "keyed by DERP Region ID", + "type": "object", + "additionalProperties": { + "type": "integer" + } + }, + "udp": { + "description": "a UDP STUN round trip completed", + "type": "boolean" + }, + "upnP": { + "description": "UPnP is whether UPnP appears present on the LAN.\nEmpty means not checked.", + "type": "string" + } + } + }, + "oauth2.Token": { + "type": "object", + "properties": { + "access_token": { + "description": "AccessToken is the token that authorizes and authenticates\nthe requests.", + "type": "string" + }, + "expiry": { + "description": "Expiry is the optional expiration time of the access token.\n\nIf zero, TokenSource implementations will reuse the same\ntoken forever and RefreshToken or equivalent\nmechanisms for that TokenSource will not be used.", + "type": "string" + }, + "refresh_token": { + "description": "RefreshToken is a token that's used by the application\n(as opposed to the user) to refresh the access token\nif it expires.", + "type": "string" + }, + "token_type": { + "description": "TokenType is the type of token.\nThe Type method returns either this or \"Bearer\", the default.", + "type": "string" + } + } + }, + "serpent.Annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "serpent.Group": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "name": { + "type": "string" + }, + "parent": { + "$ref": "#/definitions/serpent.Group" + }, + "yaml": { + "type": "string" + } + } + }, + "serpent.HostPort": { + "type": "object", + "properties": { + "host": { + "type": "string" + }, + "port": { + "type": "string" + } + } + }, + "serpent.Option": { + "type": "object", + "properties": { + "annotations": { + "description": "Annotations enable extensions to serpent higher up in the stack. It's useful for\nhelp formatting and documentation generation.", + "allOf": [ + { + "$ref": "#/definitions/serpent.Annotations" + } + ] + }, + "default": { + "description": "Default is parsed into Value if set.", + "type": "string" + }, + "description": { + "type": "string" + }, + "env": { + "description": "Env is the environment variable used to configure this option. If unset,\nenvironment configuring is disabled.", + "type": "string" + }, + "flag": { + "description": "Flag is the long name of the flag used to configure this option. If unset,\nflag configuring is disabled.", + "type": "string" + }, + "flag_shorthand": { + "description": "FlagShorthand is the one-character shorthand for the flag. If unset, no\nshorthand is used.", + "type": "string" + }, + "group": { + "description": "Group is a group hierarchy that helps organize this option in help, configs\nand other documentation.", + "allOf": [ + { + "$ref": "#/definitions/serpent.Group" + } + ] + }, + "hidden": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "required": { + "description": "Required means this value must be set by some means. It requires\n`ValueSource != ValueSourceNone`\nIf `Default` is set, then `Required` is ignored.", + "type": "boolean" + }, + "use_instead": { + "description": "UseInstead is a list of options that should be used instead of this one.\nThe field is used to generate a deprecation warning.", + "type": "array", + "items": { + "$ref": "#/definitions/serpent.Option" + } + }, + "value": { + "description": "Value includes the types listed in values.go." + }, + "value_source": { + "$ref": "#/definitions/serpent.ValueSource" + }, + "yaml": { + "description": "YAML is the YAML key used to configure this option. If unset, YAML\nconfiguring is disabled.", + "type": "string" + } + } + }, + "serpent.Regexp": { + "type": "object" + }, + "serpent.Struct-array_codersdk_ExternalAuthConfig": { + "type": "object", + "properties": { + "value": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.ExternalAuthConfig" + } + } + } + }, + "serpent.Struct-array_codersdk_LinkConfig": { + "type": "object", + "properties": { + "value": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.LinkConfig" + } + } + } + }, + "serpent.URL": { + "type": "object", + "properties": { + "forceQuery": { + "description": "append a query ('?') even if RawQuery is empty", + "type": "boolean" + }, + "fragment": { + "description": "fragment for references, without '#'", + "type": "string" + }, + "host": { + "description": "host or host:port (see Hostname and Port methods)", + "type": "string" + }, + "omitHost": { + "description": "do not emit empty host (authority)", + "type": "boolean" + }, + "opaque": { + "description": "encoded opaque data", + "type": "string" + }, + "path": { + "description": "path (relative paths may omit leading slash)", + "type": "string" + }, + "rawFragment": { + "description": "encoded fragment hint (see EscapedFragment method)", + "type": "string" + }, + "rawPath": { + "description": "encoded path hint (see EscapedPath method)", + "type": "string" + }, + "rawQuery": { + "description": "encoded query values, without '?'", + "type": "string" + }, + "scheme": { + "type": "string" + }, + "user": { + "description": "username and password information", + "allOf": [ + { + "$ref": "#/definitions/url.Userinfo" + } + ] + } + } + }, + "serpent.ValueSource": { + "type": "string", + "enum": ["", "flag", "env", "yaml", "default"], + "x-enum-varnames": [ + "ValueSourceNone", + "ValueSourceFlag", + "ValueSourceEnv", + "ValueSourceYAML", + "ValueSourceDefault" + ] + }, + "tailcfg.DERPHomeParams": { + "type": "object", + "properties": { + "regionScore": { + "description": "RegionScore scales latencies of DERP regions by a given scaling\nfactor when determining which region to use as the home\n(\"preferred\") DERP. Scores in the range (0, 1) will cause this\nregion to be proportionally more preferred, and scores in the range\n(1, ∞) will penalize a region.\n\nIf a region is not present in this map, it is treated as having a\nscore of 1.0.\n\nScores should not be 0 or negative; such scores will be ignored.\n\nA nil map means no change from the previous value (if any); an empty\nnon-nil map can be sent to reset all scores back to 1.0.", + "type": "object", + "additionalProperties": { + "type": "number" + } + } + } + }, + "tailcfg.DERPMap": { + "type": "object", + "properties": { + "homeParams": { + "description": "HomeParams, if non-nil, is a change in home parameters.\n\nThe rest of the DEPRMap fields, if zero, means unchanged.", + "allOf": [ + { + "$ref": "#/definitions/tailcfg.DERPHomeParams" + } + ] + }, + "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.\n\nThis field is only meaningful if the Regions map is non-nil (indicating a change).", + "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": { + "canPort80": { + "description": "CanPort80 specifies whether this DERP node is accessible over HTTP\non port 80 specifically. This is used for captive portal checks.", + "type": "boolean" + }, + "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" + } + } + }, + "url.Userinfo": { + "type": "object" + }, + "workspaceapps.AccessMethod": { + "type": "string", + "enum": ["path", "subdomain", "terminal"], + "x-enum-varnames": [ + "AccessMethodPath", + "AccessMethodSubdomain", + "AccessMethodTerminal" + ] + }, + "workspaceapps.IssueTokenRequest": { + "type": "object", + "properties": { + "app_hostname": { + "description": "AppHostname is the optional hostname for subdomain apps on the external\nproxy. It must start with an asterisk.", + "type": "string" + }, + "app_path": { + "description": "AppPath is the path of the user underneath the app base path.", + "type": "string" + }, + "app_query": { + "description": "AppQuery is the query parameters the user provided in the app request.", + "type": "string" + }, + "app_request": { + "$ref": "#/definitions/workspaceapps.Request" + }, + "path_app_base_url": { + "description": "PathAppBaseURL is required.", + "type": "string" + }, + "session_token": { + "description": "SessionToken is the session token provided by the user.", + "type": "string" + } + } + }, + "workspaceapps.Request": { + "type": "object", + "properties": { + "access_method": { + "$ref": "#/definitions/workspaceapps.AccessMethod" + }, + "agent_name_or_id": { + "description": "AgentNameOrID is not required if the workspace has only one agent.", + "type": "string" + }, + "app_prefix": { + "description": "Prefix is the prefix of the subdomain app URL. Prefix should have a\ntrailing \"---\" if set.", + "type": "string" + }, + "app_slug_or_port": { + "type": "string" + }, + "base_path": { + "description": "BasePath of the app. For path apps, this is the path prefix in the router\nfor this particular app. For subdomain apps, this should be \"/\". This is\nused for setting the cookie path.", + "type": "string" + }, + "username_or_id": { + "description": "For the following fields, if the AccessMethod is AccessMethodTerminal,\nthen only AgentNameOrID may be set and it must be a UUID. The other\nfields must be left blank.", + "type": "string" + }, + "workspace_name_or_id": { + "type": "string" + } + } + }, + "workspaceapps.StatsReport": { + "type": "object", + "properties": { + "access_method": { + "$ref": "#/definitions/workspaceapps.AccessMethod" + }, + "agent_id": { + "type": "string" + }, + "requests": { + "type": "integer" + }, + "session_ended_at": { + "description": "Updated periodically while app is in use active and when the last connection is closed.", + "type": "string" + }, + "session_id": { + "type": "string" + }, + "session_started_at": { + "type": "string" + }, + "slug_or_port": { + "type": "string" + }, + "user_id": { + "type": "string" + }, + "workspace_id": { + "type": "string" + } + } + }, + "workspacesdk.AgentConnectionInfo": { + "type": "object", + "properties": { + "derp_force_websockets": { + "type": "boolean" + }, + "derp_map": { + "$ref": "#/definitions/tailcfg.DERPMap" + }, + "disable_direct_connections": { + "type": "boolean" + } + } + }, + "wsproxysdk.DeregisterWorkspaceProxyRequest": { + "type": "object", + "properties": { + "replica_id": { + "description": "ReplicaID is a unique identifier for the replica of the proxy that is\nderegistering. It should be generated by the client on startup and\nshould've already been passed to the register endpoint.", + "type": "string" + } + } + }, + "wsproxysdk.IssueSignedAppTokenResponse": { + "type": "object", + "properties": { + "signed_token_str": { + "description": "SignedTokenStr should be set as a cookie on the response.", + "type": "string" + } + } + }, + "wsproxysdk.RegisterWorkspaceProxyRequest": { + "type": "object", + "properties": { + "access_url": { + "description": "AccessURL that hits the workspace proxy api.", + "type": "string" + }, + "derp_enabled": { + "description": "DerpEnabled indicates whether the proxy should be included in the DERP\nmap or not.", + "type": "boolean" + }, + "derp_only": { + "description": "DerpOnly indicates whether the proxy should only be included in the DERP\nmap and should not be used for serving apps.", + "type": "boolean" + }, + "hostname": { + "description": "ReplicaHostname is the OS hostname of the machine that the proxy is running\non. This is only used for tracking purposes in the replicas table.", + "type": "string" + }, + "replica_error": { + "description": "ReplicaError is the error that the replica encountered when trying to\ndial it's peers. This is stored in the replicas table for debugging\npurposes but does not affect the proxy's ability to register.\n\nThis value is only stored on subsequent requests to the register\nendpoint, not the first request.", + "type": "string" + }, + "replica_id": { + "description": "ReplicaID is a unique identifier for the replica of the proxy that is\nregistering. It should be generated by the client on startup and\npersisted (in memory only) until the process is restarted.", + "type": "string" + }, + "replica_relay_address": { + "description": "ReplicaRelayAddress is the DERP address of the replica that other\nreplicas may use to connect internally for DERP meshing.", + "type": "string" + }, + "version": { + "description": "Version is the Coder version of the proxy.", + "type": "string" + }, + "wildcard_hostname": { + "description": "WildcardHostname that the workspace proxy api is serving for subdomain apps.", + "type": "string" + } + } + }, + "wsproxysdk.RegisterWorkspaceProxyResponse": { + "type": "object", + "properties": { + "app_security_key": { + "type": "string" + }, + "derp_force_websockets": { + "type": "boolean" + }, + "derp_map": { + "$ref": "#/definitions/tailcfg.DERPMap" + }, + "derp_mesh_key": { + "type": "string" + }, + "derp_region_id": { + "type": "integer" + }, + "sibling_replicas": { + "description": "SiblingReplicas is a list of all other replicas of the proxy that have\nnot timed out.", + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Replica" + } + } + } + }, + "wsproxysdk.ReportAppStatsRequest": { + "type": "object", + "properties": { + "stats": { + "type": "array", + "items": { + "$ref": "#/definitions/workspaceapps.StatsReport" + } + } + } + } + }, + "securityDefinitions": { + "CoderSessionToken": { + "type": "apiKey", + "name": "Coder-Session-Token", + "in": "header" + } + } } diff --git a/coderd/rbac/input.json b/coderd/rbac/input.json index 5e464168ac..b1e8428d71 100644 --- a/coderd/rbac/input.json +++ b/coderd/rbac/input.json @@ -1,46 +1,46 @@ { - "action": "never-match-action", - "object": { - "id": "9046b041-58ed-47a3-9c3a-de302577875a", - "owner": "00000000-0000-0000-0000-000000000000", - "org_owner": "bf7b72bd-a2b1-4ef2-962c-1d698e0483f6", - "type": "workspace", - "acl_user_list": { - "f041847d-711b-40da-a89a-ede39f70dc7f": ["create"] - }, - "acl_group_list": {} - }, - "subject": { - "id": "10d03e62-7703-4df5-a358-4f76577d4e2f", - "roles": [ - { - "name": "owner", - "display_name": "Owner", - "site": [ - { - "negate": false, - "resource_type": "*", - "action": "*" - } - ], - "org": {}, - "user": [] - } - ], - "groups": ["b617a647-b5d0-4cbe-9e40-26f89710bf18"], - "scope": { - "name": "Scope_all", - "display_name": "All operations", - "site": [ - { - "negate": false, - "resource_type": "*", - "action": "*" - } - ], - "org": {}, - "user": [], - "allow_list": ["*"] - } - } + "action": "never-match-action", + "object": { + "id": "9046b041-58ed-47a3-9c3a-de302577875a", + "owner": "00000000-0000-0000-0000-000000000000", + "org_owner": "bf7b72bd-a2b1-4ef2-962c-1d698e0483f6", + "type": "workspace", + "acl_user_list": { + "f041847d-711b-40da-a89a-ede39f70dc7f": ["create"] + }, + "acl_group_list": {} + }, + "subject": { + "id": "10d03e62-7703-4df5-a358-4f76577d4e2f", + "roles": [ + { + "name": "owner", + "display_name": "Owner", + "site": [ + { + "negate": false, + "resource_type": "*", + "action": "*" + } + ], + "org": {}, + "user": [] + } + ], + "groups": ["b617a647-b5d0-4cbe-9e40-26f89710bf18"], + "scope": { + "name": "Scope_all", + "display_name": "All operations", + "site": [ + { + "negate": false, + "resource_type": "*", + "action": "*" + } + ], + "org": {}, + "user": [], + "allow_list": ["*"] + } + } } diff --git a/docs/admin/audit-logs.md b/docs/admin/audit-logs.md index ce7ee164ec..5fb017ba73 100644 --- a/docs/admin/audit-logs.md +++ b/docs/admin/audit-logs.md @@ -82,34 +82,34 @@ entry: ```json { - "ts": "2023-06-13T03:45:37.294730279Z", - "level": "INFO", - "msg": "audit_log", - "caller": "/home/runner/work/coder/coder/enterprise/audit/backends/slog.go:36", - "func": "github.com/coder/coder/enterprise/audit/backends.slogBackend.Export", - "logger_names": ["coderd"], - "fields": { - "ID": "033a9ffa-b54d-4c10-8ec3-2aaf9e6d741a", - "Time": "2023-06-13T03:45:37.288506Z", - "UserID": "6c405053-27e3-484a-9ad7-bcb64e7bfde6", - "OrganizationID": "00000000-0000-0000-0000-000000000000", - "Ip": "{IPNet:{IP:\u003cnil\u003e Mask:\u003cnil\u003e} Valid:false}", - "UserAgent": "{String: Valid:false}", - "ResourceType": "workspace_build", - "ResourceID": "ca5647e0-ef50-4202-a246-717e04447380", - "ResourceTarget": "", - "Action": "start", - "Diff": {}, - "StatusCode": 200, - "AdditionalFields": { - "workspace_name": "linux-container", - "build_number": "9", - "build_reason": "initiator", - "workspace_owner": "" - }, - "RequestID": "bb791ac3-f6ee-4da8-8ec2-f54e87013e93", - "ResourceIcon": "" - } + "ts": "2023-06-13T03:45:37.294730279Z", + "level": "INFO", + "msg": "audit_log", + "caller": "/home/runner/work/coder/coder/enterprise/audit/backends/slog.go:36", + "func": "github.com/coder/coder/enterprise/audit/backends.slogBackend.Export", + "logger_names": ["coderd"], + "fields": { + "ID": "033a9ffa-b54d-4c10-8ec3-2aaf9e6d741a", + "Time": "2023-06-13T03:45:37.288506Z", + "UserID": "6c405053-27e3-484a-9ad7-bcb64e7bfde6", + "OrganizationID": "00000000-0000-0000-0000-000000000000", + "Ip": "{IPNet:{IP:\u003cnil\u003e Mask:\u003cnil\u003e} Valid:false}", + "UserAgent": "{String: Valid:false}", + "ResourceType": "workspace_build", + "ResourceID": "ca5647e0-ef50-4202-a246-717e04447380", + "ResourceTarget": "", + "Action": "start", + "Diff": {}, + "StatusCode": 200, + "AdditionalFields": { + "workspace_name": "linux-container", + "build_number": "9", + "build_reason": "initiator", + "workspace_owner": "" + }, + "RequestID": "bb791ac3-f6ee-4da8-8ec2-f54e87013e93", + "ResourceIcon": "" + } } ``` diff --git a/docs/admin/auth.md b/docs/admin/auth.md index 4a2f4c63b8..78f46fe2c6 100644 --- a/docs/admin/auth.md +++ b/docs/admin/auth.md @@ -316,7 +316,7 @@ OIDC provider will be added to the `myCoderGroupName` group in Coder. > **Note:** Groups are only updated on login. [azure-gids]: - https://github.com/MicrosoftDocs/azure-docs/issues/59766#issuecomment-664387195 + https://github.com/MicrosoftDocs/azure-docs/issues/59766#issuecomment-664387195 ### Group allowlist diff --git a/docs/contributing/frontend.md b/docs/contributing/frontend.md index 2644c22193..8e49a67f1b 100644 --- a/docs/contributing/frontend.md +++ b/docs/contributing/frontend.md @@ -125,17 +125,17 @@ within the component's story. ```tsx export const WithQuota: Story = { - parameters: { - queries: [ - { - key: getWorkspaceQuotaQueryKey(MockUser.username), - data: { - credits_consumed: 2, - budget: 40, - }, - }, - ], - }, + parameters: { + queries: [ + { + key: getWorkspaceQuotaQueryKey(MockUser.username), + data: { + credits_consumed: 2, + budget: 40, + }, + }, + ], + }, }; ``` @@ -150,12 +150,12 @@ example below: ```ts export const getAgentListeningPorts = async ( - agentID: string, + agentID: string, ): Promise => { - const response = await axiosInstance.get( - `/api/v2/workspaceagents/${agentID}/listening-ports`, - ); - return response.data; + const response = await axiosInstance.get( + `/api/v2/workspaceagents/${agentID}/listening-ports`, + ); + return response.data; }; ``` @@ -164,10 +164,10 @@ wrap it as a single function. ```ts export const updateWorkspaceVersion = async ( - workspace: TypesGen.Workspace, + workspace: TypesGen.Workspace, ): Promise => { - const template = await getTemplate(workspace.template_id); - return startWorkspace(workspace.id, template.active_version_id); + const template = await getTemplate(workspace.template_id); + return startWorkspace(workspace.id, template.active_version_id); }; ``` @@ -214,10 +214,10 @@ inside the component itself using MUI's `visuallyHidden` utility function. import { visuallyHidden } from "@mui/utils"; ; ``` diff --git a/docs/guides/gcp-to-aws.md b/docs/guides/gcp-to-aws.md index 950db68e77..07eabefe19 100644 --- a/docs/guides/gcp-to-aws.md +++ b/docs/guides/gcp-to-aws.md @@ -39,21 +39,21 @@ following: ```json { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Principal": { - "Federated": "accounts.google.com" - }, - "Action": "sts:AssumeRoleWithWebIdentity", - "Condition": { - "StringEquals": { - "accounts.google.com:aud": "": { - "username": "", - "password": "" - } - } + "auths": { + "": { + "username": "", + "password": "" + } + } } ``` @@ -54,13 +54,13 @@ The output should look similar to this: ```json { - "auths": { - "your.private.registry.com": { - "username": "ericpaulsen", - "password": "xxxx", - "auth": "c3R...zE2" - } - } + "auths": { + "your.private.registry.com": { + "username": "ericpaulsen", + "password": "xxxx", + "auth": "c3R...zE2" + } + } } ``` diff --git a/docs/manifest.json b/docs/manifest.json index b35a8d2a7b..149262c5cc 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -1,1184 +1,1184 @@ { - "versions": ["main"], - "routes": [ - { - "title": "About", - "description": "About Coder", - "path": "./README.md", - "icon_path": "./images/icons/home.svg", - "children": [ - { - "title": "Screenshots", - "description": "Browse screenshots of the Coder platform", - "path": "./about/screenshots.md" - } - ] - }, - { - "title": "Architecture", - "description": "Learn about validated and reference architectures for Coder", - "path": "./architecture/architecture.md", - "icon_path": "./images/icons/container.svg", - "children": [ - { - "title": "Validated Architecture", - "path": "./architecture/validated-arch.md" - }, - { - "title": "Up to 1,000 users", - "path": "./architecture/1k-users.md" - }, - { - "title": "Up to 2,000 users", - "path": "./architecture/2k-users.md" - }, - { - "title": "Up to 3,000 users", - "path": "./architecture/3k-users.md" - } - ] - }, - { - "title": "Installation", - "description": "How to install and deploy Coder", - "path": "./install/index.md", - "icon_path": "./images/icons/download.svg", - "children": [ - { - "title": "Kubernetes", - "description": "Install Coder with Kubernetes via Helm", - "path": "./install/kubernetes.md" - }, - { - "title": "Docker", - "description": "Install Coder with Docker / docker-compose", - "path": "./install/docker.md" - }, - { - "title": "OpenShift", - "description": "Install Coder on OpenShift", - "path": "./install/openshift.md" - }, - { - "title": "Offline deployments", - "description": "Run Coder in offline / air-gapped environments", - "path": "./install/offline.md" - }, - { - "title": "External database", - "description": "Use external PostgreSQL database", - "path": "./install/database.md" - }, - { - "title": "Uninstall", - "description": "Learn how to uninstall Coder", - "path": "./install/uninstall.md" - }, - { - "title": "1-click install", - "description": "Install Coder on a cloud provider with a single click", - "path": "./install/1-click.md" - }, - { - "title": "Releases", - "description": "Coder Release Channels and Cadence", - "path": "./install/releases.md" - } - ] - }, - { - "title": "Platforms", - "description": "Platform-specific guides using Coder", - "path": "./platforms/README.md", - "icon_path": "./images/icons/star.svg", - "children": [ - { - "title": "AWS", - "description": "Set up Coder on an AWS EC2 VM", - "path": "./platforms/aws.md", - "icon_path": "./images/aws.svg" - }, - { - "title": "Azure", - "description": "Set up Coder on an Azure VM", - "path": "./platforms/azure.md", - "icon_path": "./images/azure.svg" - }, - { - "title": "Docker", - "description": "Set up Coder with Docker", - "path": "./platforms/docker.md", - "icon_path": "./images/icons/docker.svg" - }, - { - "title": "GCP", - "description": "Set up Coder on a GCP Compute Engine VM", - "path": "./platforms/gcp.md", - "icon_path": "./images/google-cloud.svg" - }, - { - "title": "Kubernetes", - "description": "Set up Coder on Kubernetes", - "path": "./platforms/kubernetes/index.md", - "children": [ - { - "title": "Additional clusters", - "description": "Deploy workspaces on additional Kubernetes clusters", - "path": "./platforms/kubernetes/additional-clusters.md" - }, - { - "title": "Deployment logs", - "description": "Stream K8s event logs on workspace startup", - "path": "./platforms/kubernetes/deployment-logs.md" - } - ] - }, - { - "title": "Other platforms", - "description": "Set up Coder on an another provider", - "path": "./platforms/other.md" - } - ] - }, - { - "title": "Templates", - "description": "Templates define the infrastructure for workspaces", - "path": "./templates/index.md", - "icon_path": "./images/icons/picture.svg", - "children": [ - { - "title": "Working with templates", - "description": "Creating, editing, and updating templates", - "path": "./templates/creating.md" - }, - { - "title": "Your first template", - "description": "A tutorial for creating and editing your first template", - "path": "./templates/tutorial.md" - }, - { - "title": "Guided tour", - "description": "Create a template from scratch", - "path": "./templates/tour.md" - }, - { - "title": "Setting up templates", - "description": "Best practices for writing templates", - "path": "./templates/best-practices.md", - "children": [ - { - "title": "Template Dependencies", - "description": "Manage dependencies of your templates", - "path": "./templates/dependencies.md", - "icon_path": "./images/icons/dependency.svg" - }, - { - "title": "Change management", - "description": "Versioning templates with git and CI", - "path": "./templates/change-management.md", - "icon_path": "./images/icons/git.svg" - }, - { - "title": "Provider authentication", - "description": "Authenticate the provisioner", - "path": "./templates/authentication.md", - "icon_path": "./images/icons/key.svg" - }, - { - "title": "Resource persistence", - "description": "How resource persistence works in Coder", - "path": "./templates/resource-persistence.md", - "icon_path": "./images/icons/infinity.svg" - }, - { - "title": "Terraform modules", - "description": "Reuse code across Coder templates", - "path": "./templates/modules.md" - } - ] - }, - { - "title": "Customizing templates", - "description": "Give information and options to workspace users", - "path": "./templates/customizing.md", - "children": [ - { - "title": "Agent metadata", - "description": "Show operational metrics in the workspace", - "path": "./templates/agent-metadata.md" - }, - { - "title": "Resource metadata", - "description": "Show information in the workspace about template resources", - "path": "./templates/resource-metadata.md" - }, - { - "title": "UI Resource Ordering", - "description": "Learn how to manage the order of Terraform resources in UI", - "path": "./templates/resource-ordering.md" - } - ] - }, - { - "title": "Parameters", - "description": "Prompt the user for additional information about a workspace", - "path": "./templates/parameters.md" - }, - { - "title": "Variables", - "description": "Prompt the template administrator for additional information about a template", - "path": "./templates/variables.md" - }, - { - "title": "Workspace Tags", - "description": "Control provisioning using Workspace Tags and Parameters", - "path": "./templates/workspace-tags.md" - }, - { - "title": "Administering templates", - "description": "Configuration settings for template admins", - "path": "./templates/configuration.md", - "children": [ - { - "title": "General settings", - "description": "Configure name, display info, and update polices", - "path": "./templates/general-settings.md" - }, - { - "title": "Permissions", - "description": "Configure who can access a template", - "path": "./templates/permissions.md" - }, - { - "title": "Workspace Scheduling", - "description": "Configure when workspaces start, stop, and delete", - "path": "./templates/schedule.md" - } - ] - }, - { - "title": "Open in Coder", - "description": "Add an \"Open in Coder\" button to your repos", - "path": "./templates/open-in-coder.md", - "icon_path": "./images/icons/key.svg" - }, - { - "title": "Docker in workspaces", - "description": "Use Docker inside containerized templates", - "path": "./templates/docker-in-workspaces.md", - "icon_path": "./images/icons/docker.svg" - }, - { - "title": "Dev Containers", - "description": "Use Dev Containers in workspaces", - "path": "./templates/dev-containers.md", - "state": "alpha" - }, - { - "title": "Troubleshooting templates", - "description": "Fix common template problems", - "path": "./templates/troubleshooting.md" - }, - { - "title": "Process Logging", - "description": "Audit commands in workspaces with exectrace", - "path": "./templates/process-logging.md", - "state": "enterprise" - }, - { - "title": "Icons", - "description": "Coder includes icons for popular cloud providers and programming languages for you to use", - "path": "./templates/icons.md" - } - ] - }, - { - "title": "Workspaces", - "description": "Learn about Coder workspaces.", - "path": "./workspaces.md", - "icon_path": "./images/icons/layers.svg" - }, - { - "title": "IDEs", - "description": "Learn how to use your IDE of choice with Coder", - "path": "./ides.md", - "icon_path": "./images/icons/code.svg", - "children": [ - { - "title": "Web IDEs", - "description": "Learn how to configure web IDEs in your templates", - "path": "./ides/web-ides.md" - }, - { - "title": "JetBrains Gateway", - "description": "Learn how to configure JetBrains Gateway for your workspaces", - "path": "./ides/gateway.md" - }, - { - "title": "JetBrains Fleet", - "description": "Learn how to configure JetBrains Fleet for your workspaces", - "path": "./ides/fleet.md" - }, - { - "title": "Emacs", - "description": "Learn how to configure Emacs with TRAMP in Coder", - "path": "./ides/emacs-tramp.md" - }, - { - "title": "Remote Desktops", - "description": "Learn how to use Remote Desktops with Coder", - "path": "./ides/remote-desktops.md" - } - ] - }, - { - "title": "Networking", - "description": "Learn about networking in Coder", - "path": "./networking/index.md", - "icon_path": "./images/icons/networking.svg", - "children": [ - { - "title": "Port Forwarding", - "description": "Learn how to forward ports in Coder", - "path": "./networking/port-forwarding.md" - }, - { - "title": "STUN and NAT", - "description": "Learn how Coder establishes direct connections", - "path": "./networking/stun.md" - } - ] - }, - { - "title": "Dotfiles", - "description": "Learn how to personalize your workspace", - "path": "./dotfiles.md", - "icon_path": "./images/icons/art-pad.svg" - }, - { - "title": "Secrets", - "description": "Learn how to use secrets in your workspace", - "path": "./secrets.md", - "icon_path": "./images/icons/secrets.svg" - }, - { - "title": "Administration", - "description": "How to install and deploy Coder", - "path": "./admin/README.md", - "icon_path": "./images/icons/wrench.svg", - "children": [ - { - "title": "Authentication", - "description": "Learn how to set up authentication using GitHub or OpenID Connect", - "path": "./admin/auth.md", - "icon_path": "./images/icons/key.svg" - }, - { - "title": "Users", - "description": "Learn about user roles available in Coder and how to create and manage users", - "path": "./admin/users.md", - "icon_path": "./images/icons/users.svg" - }, - { - "title": "Groups", - "description": "Learn how to manage user groups", - "path": "./admin/groups.md", - "icon_path": "./images/icons/group.svg", - "state": "enterprise" - }, - { - "title": "RBAC", - "description": "Learn how to use the role based access control", - "path": "./admin/rbac.md", - "icon_path": "./images/icons/rbac.svg", - "state": "enterprise" - }, - { - "title": "Configuration", - "description": "Learn how to configure Coder", - "path": "./admin/configure.md", - "icon_path": "./images/icons/toggle_on.svg" - }, - { - "title": "External Auth", - "description": "Learn how connect Coder with external auth providers", - "path": "./admin/external-auth.md", - "icon_path": "./images/icons/git.svg" - }, - { - "title": "Upgrading", - "description": "Learn how to upgrade Coder", - "path": "./admin/upgrade.md", - "icon_path": "./images/icons/upgrade.svg" - }, - { - "title": "Automation", - "description": "Learn how to automate Coder with the CLI and API", - "path": "./admin/automation.md", - "icon_path": "./images/icons/plug.svg" - }, - { - "title": "Scaling Coder", - "description": "Learn how to use load testing tools", - "path": "./admin/scaling/scale-testing.md", - "icon_path": "./images/icons/scale.svg", - "children": [ - { - "title": "Scaling Utility", - "path": "./admin/scaling/scale-utility.md" - } - ] - }, - { - "title": "External Provisioners", - "description": "Run provisioners isolated from the Coder server", - "path": "./admin/provisioners.md", - "icon_path": "./images/icons/queue.svg", - "state": "enterprise" - }, - { - "title": "Workspace Proxies", - "description": "Run geo distributed workspace proxies", - "path": "./admin/workspace-proxies.md", - "icon_path": "./images/icons/networking.svg", - "state": "enterprise" - }, - { - "title": "Application Logs", - "description": "Learn how to use Application Logs in your Coder deployment", - "path": "./admin/app-logs.md", - "icon_path": "./images/icons/notes.svg" - }, - { - "title": "Audit Logs", - "description": "Learn how to use Audit Logs in your Coder deployment", - "path": "./admin/audit-logs.md", - "icon_path": "./images/icons/radar.svg", - "state": "enterprise" - }, - { - "title": "Quotas", - "description": "Learn how to use Workspace Quotas in Coder", - "path": "./admin/quotas.md", - "icon_path": "./images/icons/dollar.svg", - "state": "enterprise" - }, - { - "title": "High Availability", - "description": "Learn how to configure Coder for High Availability", - "path": "./admin/high-availability.md", - "icon_path": "./images/icons/hydra.svg", - "state": "enterprise" - }, - { - "title": "Prometheus", - "description": "Learn how to collect Prometheus metrics", - "path": "./admin/prometheus.md", - "icon_path": "./images/icons/speed.svg" - }, - { - "title": "Appearance", - "description": "Learn how to configure the appearance of Coder", - "path": "./admin/appearance.md", - "icon_path": "./images/icons/info.svg", - "state": "enterprise" - }, - { - "title": "Telemetry", - "description": "Learn what usage telemetry Coder collects", - "path": "./admin/telemetry.md", - "icon_path": "./images/icons/science.svg" - }, - { - "title": "Database Encryption", - "description": "Learn how to encrypt sensitive data at rest in Coder", - "path": "./admin/encryption.md", - "icon_path": "./images/icons/lock.svg", - "state": "enterprise" - }, - { - "title": "Deployment Health", - "description": "Learn how to monitor the health of your Coder deployment", - "path": "./admin/healthcheck.md", - "icon_path": "./images/icons/health.svg" - } - ] - }, - { - "title": "Enterprise", - "description": "Learn how to enable Enterprise features", - "path": "./enterprise.md", - "icon_path": "./images/icons/group.svg" - }, - { - "title": "Contributing", - "description": "Learn how to contribute to Coder", - "path": "./CONTRIBUTING.md", - "icon_path": "./images/icons/contributing.svg", - "children": [ - { - "title": "Code of Conduct", - "description": "See the code of conduct for contributing to Coder", - "path": "./contributing/CODE_OF_CONDUCT.md" - }, - { - "title": "Feature stages", - "description": "Policies for Alpha and Experimental features.", - "path": "./contributing/feature-stages.md" - }, - { - "title": "Documentation", - "description": "Our style guide for use when authoring documentation", - "path": "./contributing/documentation.md" - }, - { - "title": "Security", - "description": "How to report vulnerabilities in Coder", - "path": "./contributing/SECURITY.md" - }, - { - "title": "Frontend", - "description": "Our guide for frontend development", - "path": "./contributing/frontend.md" - } - ] - }, - { - "title": "Reference", - "description": "Reference", - "path": "./reference/README.md", - "icon_path": "./images/icons/notes.svg", - "children": [ - { - "title": "REST API", - "description": "Learn how to use Coderd API", - "path": "./reference/api/README.md", - "icon_path": "./images/icons/api.svg", - "children": [ - { - "title": "General", - "path": "./reference/api/general.md" - }, - { - "title": "Agents", - "path": "./reference/api/agents.md" - }, - { - "title": "Applications", - "path": "./reference/api/applications.md" - }, - { - "title": "Audit", - "path": "./reference/api/audit.md" - }, - { - "title": "Authentication", - "path": "./reference/api/authentication.md" - }, - { - "title": "Authorization", - "path": "./reference/api/authorization.md" - }, - { - "title": "Builds", - "path": "./reference/api/builds.md" - }, - { - "title": "Debug", - "path": "./reference/api/debug.md" - }, - { - "title": "Enterprise", - "path": "./reference/api/enterprise.md" - }, - { - "title": "Files", - "path": "./reference/api/files.md" - }, - { - "title": "Git", - "path": "./reference/api/git.md" - }, - { - "title": "Insights", - "path": "./reference/api/insights.md" - }, - { - "title": "Members", - "path": "./reference/api/members.md" - }, - { - "title": "Organizations", - "path": "./reference/api/organizations.md" - }, - { - "title": "PortSharing", - "path": "./reference/api/portsharing.md" - }, - { - "title": "Schemas", - "path": "./reference/api/schemas.md" - }, - { - "title": "Templates", - "path": "./reference/api/templates.md" - }, - { - "title": "Users", - "path": "./reference/api/users.md" - }, - { - "title": "WorkspaceProxies", - "path": "./reference/api/workspaceproxies.md" - }, - { - "title": "Workspaces", - "path": "./reference/api/workspaces.md" - } - ] - }, - { - "title": "Command Line", - "description": "Learn how to use Coder CLI", - "path": "./reference/cli/README.md", - "icon_path": "./images/icons/terminal.svg", - "children": [ - { - "title": "autoupdate", - "description": "Toggle auto-update policy for a workspace", - "path": "reference/cli/autoupdate.md" - }, - { - "title": "coder", - "path": "reference/cli/README.md" - }, - { - "title": "config-ssh", - "description": "Add an SSH Host entry for your workspaces \"ssh coder.workspace\"", - "path": "reference/cli/config-ssh.md" - }, - { - "title": "create", - "description": "Create a workspace", - "path": "reference/cli/create.md" - }, - { - "title": "delete", - "description": "Delete a workspace", - "path": "reference/cli/delete.md" - }, - { - "title": "dotfiles", - "description": "Personalize your workspace by applying a canonical dotfiles repository", - "path": "reference/cli/dotfiles.md" - }, - { - "title": "external-auth", - "description": "Manage external authentication", - "path": "reference/cli/external-auth.md" - }, - { - "title": "external-auth access-token", - "description": "Print auth for an external provider", - "path": "reference/cli/external-auth_access-token.md" - }, - { - "title": "favorite", - "description": "Add a workspace to your favorites", - "path": "reference/cli/favorite.md" - }, - { - "title": "features", - "description": "List Enterprise features", - "path": "reference/cli/features.md" - }, - { - "title": "features list", - "path": "reference/cli/features_list.md" - }, - { - "title": "groups", - "description": "Manage groups", - "path": "reference/cli/groups.md" - }, - { - "title": "groups create", - "description": "Create a user group", - "path": "reference/cli/groups_create.md" - }, - { - "title": "groups delete", - "description": "Delete a user group", - "path": "reference/cli/groups_delete.md" - }, - { - "title": "groups edit", - "description": "Edit a user group", - "path": "reference/cli/groups_edit.md" - }, - { - "title": "groups list", - "description": "List user groups", - "path": "reference/cli/groups_list.md" - }, - { - "title": "licenses", - "description": "Add, delete, and list licenses", - "path": "reference/cli/licenses.md" - }, - { - "title": "licenses add", - "description": "Add license to Coder deployment", - "path": "reference/cli/licenses_add.md" - }, - { - "title": "licenses delete", - "description": "Delete license by ID", - "path": "reference/cli/licenses_delete.md" - }, - { - "title": "licenses list", - "description": "List licenses (including expired)", - "path": "reference/cli/licenses_list.md" - }, - { - "title": "list", - "description": "List workspaces", - "path": "reference/cli/list.md" - }, - { - "title": "login", - "description": "Authenticate with Coder deployment", - "path": "reference/cli/login.md" - }, - { - "title": "logout", - "description": "Unauthenticate your local session", - "path": "reference/cli/logout.md" - }, - { - "title": "netcheck", - "description": "Print network debug information for DERP and STUN", - "path": "reference/cli/netcheck.md" - }, - { - "title": "notifications", - "description": "Manage Coder notifications", - "path": "reference/cli/notifications.md" - }, - { - "title": "notifications pause", - "description": "Pause notifications", - "path": "reference/cli/notifications_pause.md" - }, - { - "title": "notifications resume", - "description": "Resume notifications", - "path": "reference/cli/notifications_resume.md" - }, - { - "title": "open", - "description": "Open a workspace", - "path": "reference/cli/open.md" - }, - { - "title": "open vscode", - "description": "Open a workspace in VS Code Desktop", - "path": "reference/cli/open_vscode.md" - }, - { - "title": "ping", - "description": "Ping a workspace", - "path": "reference/cli/ping.md" - }, - { - "title": "port-forward", - "description": "Forward ports from a workspace to the local machine. For reverse port forwarding, use \"coder ssh -R\".", - "path": "reference/cli/port-forward.md" - }, - { - "title": "provisionerd", - "description": "Manage provisioner daemons", - "path": "reference/cli/provisionerd.md" - }, - { - "title": "provisionerd start", - "description": "Run a provisioner daemon", - "path": "reference/cli/provisionerd_start.md" - }, - { - "title": "publickey", - "description": "Output your Coder public key used for Git operations", - "path": "reference/cli/publickey.md" - }, - { - "title": "rename", - "description": "Rename a workspace", - "path": "reference/cli/rename.md" - }, - { - "title": "reset-password", - "description": "Directly connect to the database to reset a user's password", - "path": "reference/cli/reset-password.md" - }, - { - "title": "restart", - "description": "Restart a workspace", - "path": "reference/cli/restart.md" - }, - { - "title": "schedule", - "description": "Schedule automated start and stop times for workspaces", - "path": "reference/cli/schedule.md" - }, - { - "title": "schedule override-stop", - "description": "Override the stop time of a currently running workspace instance.", - "path": "reference/cli/schedule_override-stop.md" - }, - { - "title": "schedule show", - "description": "Show workspace schedules", - "path": "reference/cli/schedule_show.md" - }, - { - "title": "schedule start", - "description": "Edit workspace start schedule", - "path": "reference/cli/schedule_start.md" - }, - { - "title": "schedule stop", - "description": "Edit workspace stop schedule", - "path": "reference/cli/schedule_stop.md" - }, - { - "title": "server", - "description": "Start a Coder server", - "path": "reference/cli/server.md" - }, - { - "title": "server create-admin-user", - "description": "Create a new admin user with the given username, email and password and adds it to every organization.", - "path": "reference/cli/server_create-admin-user.md" - }, - { - "title": "server dbcrypt", - "description": "Manage database encryption.", - "path": "reference/cli/server_dbcrypt.md" - }, - { - "title": "server dbcrypt decrypt", - "description": "Decrypt a previously encrypted database.", - "path": "reference/cli/server_dbcrypt_decrypt.md" - }, - { - "title": "server dbcrypt delete", - "description": "Delete all encrypted data from the database. THIS IS A DESTRUCTIVE OPERATION.", - "path": "reference/cli/server_dbcrypt_delete.md" - }, - { - "title": "server dbcrypt rotate", - "description": "Rotate database encryption keys.", - "path": "reference/cli/server_dbcrypt_rotate.md" - }, - { - "title": "server postgres-builtin-serve", - "description": "Run the built-in PostgreSQL deployment.", - "path": "reference/cli/server_postgres-builtin-serve.md" - }, - { - "title": "server postgres-builtin-url", - "description": "Output the connection URL for the built-in PostgreSQL deployment.", - "path": "reference/cli/server_postgres-builtin-url.md" - }, - { - "title": "show", - "description": "Display details of a workspace's resources and agents", - "path": "reference/cli/show.md" - }, - { - "title": "speedtest", - "description": "Run upload and download tests from your machine to a workspace", - "path": "reference/cli/speedtest.md" - }, - { - "title": "ssh", - "description": "Start a shell into a workspace", - "path": "reference/cli/ssh.md" - }, - { - "title": "start", - "description": "Start a workspace", - "path": "reference/cli/start.md" - }, - { - "title": "stat", - "description": "Show resource usage for the current workspace.", - "path": "reference/cli/stat.md" - }, - { - "title": "stat cpu", - "description": "Show CPU usage, in cores.", - "path": "reference/cli/stat_cpu.md" - }, - { - "title": "stat disk", - "description": "Show disk usage, in gigabytes.", - "path": "reference/cli/stat_disk.md" - }, - { - "title": "stat mem", - "description": "Show memory usage, in gigabytes.", - "path": "reference/cli/stat_mem.md" - }, - { - "title": "state", - "description": "Manually manage Terraform state to fix broken workspaces", - "path": "reference/cli/state.md" - }, - { - "title": "state pull", - "description": "Pull a Terraform state file from a workspace.", - "path": "reference/cli/state_pull.md" - }, - { - "title": "state push", - "description": "Push a Terraform state file to a workspace.", - "path": "reference/cli/state_push.md" - }, - { - "title": "stop", - "description": "Stop a workspace", - "path": "reference/cli/stop.md" - }, - { - "title": "support", - "description": "Commands for troubleshooting issues with a Coder deployment.", - "path": "reference/cli/support.md" - }, - { - "title": "support bundle", - "description": "Generate a support bundle to troubleshoot issues connecting to a workspace.", - "path": "reference/cli/support_bundle.md" - }, - { - "title": "templates", - "description": "Manage templates", - "path": "reference/cli/templates.md" - }, - { - "title": "templates archive", - "description": "Archive unused or failed template versions from a given template(s)", - "path": "reference/cli/templates_archive.md" - }, - { - "title": "templates create", - "description": "DEPRECATED: Create a template from the current directory or as specified by flag", - "path": "reference/cli/templates_create.md" - }, - { - "title": "templates delete", - "description": "Delete templates", - "path": "reference/cli/templates_delete.md" - }, - { - "title": "templates edit", - "description": "Edit the metadata of a template by name.", - "path": "reference/cli/templates_edit.md" - }, - { - "title": "templates init", - "description": "Get started with a templated template.", - "path": "reference/cli/templates_init.md" - }, - { - "title": "templates list", - "description": "List all the templates available for the organization", - "path": "reference/cli/templates_list.md" - }, - { - "title": "templates pull", - "description": "Download the active, latest, or specified version of a template to a path.", - "path": "reference/cli/templates_pull.md" - }, - { - "title": "templates push", - "description": "Create or update a template from the current directory or as specified by flag", - "path": "reference/cli/templates_push.md" - }, - { - "title": "templates versions", - "description": "Manage different versions of the specified template", - "path": "reference/cli/templates_versions.md" - }, - { - "title": "templates versions archive", - "description": "Archive a template version(s).", - "path": "reference/cli/templates_versions_archive.md" - }, - { - "title": "templates versions list", - "description": "List all the versions of the specified template", - "path": "reference/cli/templates_versions_list.md" - }, - { - "title": "templates versions unarchive", - "description": "Unarchive a template version(s).", - "path": "reference/cli/templates_versions_unarchive.md" - }, - { - "title": "tokens", - "description": "Manage personal access tokens", - "path": "reference/cli/tokens.md" - }, - { - "title": "tokens create", - "description": "Create a token", - "path": "reference/cli/tokens_create.md" - }, - { - "title": "tokens list", - "description": "List tokens", - "path": "reference/cli/tokens_list.md" - }, - { - "title": "tokens remove", - "description": "Delete a token", - "path": "reference/cli/tokens_remove.md" - }, - { - "title": "unfavorite", - "description": "Remove a workspace from your favorites", - "path": "reference/cli/unfavorite.md" - }, - { - "title": "update", - "description": "Will update and start a given workspace if it is out of date", - "path": "reference/cli/update.md" - }, - { - "title": "users", - "description": "Manage users", - "path": "reference/cli/users.md" - }, - { - "title": "users activate", - "description": "Update a user's status to 'active'. Active users can fully interact with the platform", - "path": "reference/cli/users_activate.md" - }, - { - "title": "users create", - "path": "reference/cli/users_create.md" - }, - { - "title": "users delete", - "description": "Delete a user by username or user_id.", - "path": "reference/cli/users_delete.md" - }, - { - "title": "users list", - "path": "reference/cli/users_list.md" - }, - { - "title": "users show", - "description": "Show a single user. Use 'me' to indicate the currently authenticated user.", - "path": "reference/cli/users_show.md" - }, - { - "title": "users suspend", - "description": "Update a user's status to 'suspended'. A suspended user cannot log into the platform", - "path": "reference/cli/users_suspend.md" - }, - { - "title": "version", - "description": "Show coder version", - "path": "reference/cli/version.md" - }, - { - "title": "whoami", - "description": "Fetch authenticated user info for Coder deployment", - "path": "reference/cli/whoami.md" - } - ] - } - ] - }, - { - "title": "Security", - "description": "Security advisories", - "path": "./security/index.md", - "icon_path": "./images/icons/security.svg", - "children": [ - { - "title": "API tokens of deleted users not invalidated", - "description": "Fixed in v0.23.0 (Apr 25, 2023)", - "path": "./security/0001_user_apikeys_invalidation.md" - } - ] - }, - { - "title": "FAQs", - "description": "Frequently asked questions", - "path": "./faqs.md", - "icon_path": "./images/icons/info.svg" - }, - { - "title": "Guides", - "description": "Employee-authored tutorials", - "path": "./guides/index.md", - "icon_path": "./images/icons/notes.svg", - "children": [ - { - "title": "Generate a Support Bundle", - "description": "Generate and upload a Support Bundle to Coder Support", - "path": "./guides/support-bundle.md" - }, - { - "title": "Configuring Okta", - "description": "Custom claims/scopes with Okta for group/role sync", - "path": "./guides/configuring-okta.md" - }, - { - "title": "Google to AWS Federation", - "description": "Federating a Google Cloud service account to AWS", - "path": "./guides/gcp-to-aws.md" - }, - { - "title": "JFrog Artifactory Integration", - "description": "Integrate Coder with JFrog Artifactory", - "path": "./guides/artifactory-integration.md" - }, - { - "title": "Island Enterprise Browser Integration", - "description": "Integrate Coder with Island's Enterprise Browser", - "path": "./guides/island-integration.md" - }, - { - "title": "Template ImagePullSecrets", - "description": "Creating ImagePullSecrets for private registries", - "path": "./guides/image-pull-secret.md" - }, - { - "title": "Postgres SSL", - "description": "Configure Coder to connect to Postgres over SSL", - "path": "./guides/postgres-ssl.md" - }, - { - "title": "Azure Federation", - "description": "Federating Coder to Azure", - "path": "./guides/azure-federation.md" - }, - { - "title": "Scanning Coder Workspaces with JFrog Xray", - "description": "Integrate Coder with JFrog Xray", - "path": "./guides/xray-integration.md" - }, - { - "title": "Cloning Git Repositories", - "description": "Automatically clone Git repositories into your workspace", - "path": "./guides/cloning-git-repositories.md" - } - ] - } - ] + "versions": ["main"], + "routes": [ + { + "title": "About", + "description": "About Coder", + "path": "./README.md", + "icon_path": "./images/icons/home.svg", + "children": [ + { + "title": "Screenshots", + "description": "Browse screenshots of the Coder platform", + "path": "./about/screenshots.md" + } + ] + }, + { + "title": "Architecture", + "description": "Learn about validated and reference architectures for Coder", + "path": "./architecture/architecture.md", + "icon_path": "./images/icons/container.svg", + "children": [ + { + "title": "Validated Architecture", + "path": "./architecture/validated-arch.md" + }, + { + "title": "Up to 1,000 users", + "path": "./architecture/1k-users.md" + }, + { + "title": "Up to 2,000 users", + "path": "./architecture/2k-users.md" + }, + { + "title": "Up to 3,000 users", + "path": "./architecture/3k-users.md" + } + ] + }, + { + "title": "Installation", + "description": "How to install and deploy Coder", + "path": "./install/index.md", + "icon_path": "./images/icons/download.svg", + "children": [ + { + "title": "Kubernetes", + "description": "Install Coder with Kubernetes via Helm", + "path": "./install/kubernetes.md" + }, + { + "title": "Docker", + "description": "Install Coder with Docker / docker-compose", + "path": "./install/docker.md" + }, + { + "title": "OpenShift", + "description": "Install Coder on OpenShift", + "path": "./install/openshift.md" + }, + { + "title": "Offline deployments", + "description": "Run Coder in offline / air-gapped environments", + "path": "./install/offline.md" + }, + { + "title": "External database", + "description": "Use external PostgreSQL database", + "path": "./install/database.md" + }, + { + "title": "Uninstall", + "description": "Learn how to uninstall Coder", + "path": "./install/uninstall.md" + }, + { + "title": "1-click install", + "description": "Install Coder on a cloud provider with a single click", + "path": "./install/1-click.md" + }, + { + "title": "Releases", + "description": "Coder Release Channels and Cadence", + "path": "./install/releases.md" + } + ] + }, + { + "title": "Platforms", + "description": "Platform-specific guides using Coder", + "path": "./platforms/README.md", + "icon_path": "./images/icons/star.svg", + "children": [ + { + "title": "AWS", + "description": "Set up Coder on an AWS EC2 VM", + "path": "./platforms/aws.md", + "icon_path": "./images/aws.svg" + }, + { + "title": "Azure", + "description": "Set up Coder on an Azure VM", + "path": "./platforms/azure.md", + "icon_path": "./images/azure.svg" + }, + { + "title": "Docker", + "description": "Set up Coder with Docker", + "path": "./platforms/docker.md", + "icon_path": "./images/icons/docker.svg" + }, + { + "title": "GCP", + "description": "Set up Coder on a GCP Compute Engine VM", + "path": "./platforms/gcp.md", + "icon_path": "./images/google-cloud.svg" + }, + { + "title": "Kubernetes", + "description": "Set up Coder on Kubernetes", + "path": "./platforms/kubernetes/index.md", + "children": [ + { + "title": "Additional clusters", + "description": "Deploy workspaces on additional Kubernetes clusters", + "path": "./platforms/kubernetes/additional-clusters.md" + }, + { + "title": "Deployment logs", + "description": "Stream K8s event logs on workspace startup", + "path": "./platforms/kubernetes/deployment-logs.md" + } + ] + }, + { + "title": "Other platforms", + "description": "Set up Coder on an another provider", + "path": "./platforms/other.md" + } + ] + }, + { + "title": "Templates", + "description": "Templates define the infrastructure for workspaces", + "path": "./templates/index.md", + "icon_path": "./images/icons/picture.svg", + "children": [ + { + "title": "Working with templates", + "description": "Creating, editing, and updating templates", + "path": "./templates/creating.md" + }, + { + "title": "Your first template", + "description": "A tutorial for creating and editing your first template", + "path": "./templates/tutorial.md" + }, + { + "title": "Guided tour", + "description": "Create a template from scratch", + "path": "./templates/tour.md" + }, + { + "title": "Setting up templates", + "description": "Best practices for writing templates", + "path": "./templates/best-practices.md", + "children": [ + { + "title": "Template Dependencies", + "description": "Manage dependencies of your templates", + "path": "./templates/dependencies.md", + "icon_path": "./images/icons/dependency.svg" + }, + { + "title": "Change management", + "description": "Versioning templates with git and CI", + "path": "./templates/change-management.md", + "icon_path": "./images/icons/git.svg" + }, + { + "title": "Provider authentication", + "description": "Authenticate the provisioner", + "path": "./templates/authentication.md", + "icon_path": "./images/icons/key.svg" + }, + { + "title": "Resource persistence", + "description": "How resource persistence works in Coder", + "path": "./templates/resource-persistence.md", + "icon_path": "./images/icons/infinity.svg" + }, + { + "title": "Terraform modules", + "description": "Reuse code across Coder templates", + "path": "./templates/modules.md" + } + ] + }, + { + "title": "Customizing templates", + "description": "Give information and options to workspace users", + "path": "./templates/customizing.md", + "children": [ + { + "title": "Agent metadata", + "description": "Show operational metrics in the workspace", + "path": "./templates/agent-metadata.md" + }, + { + "title": "Resource metadata", + "description": "Show information in the workspace about template resources", + "path": "./templates/resource-metadata.md" + }, + { + "title": "UI Resource Ordering", + "description": "Learn how to manage the order of Terraform resources in UI", + "path": "./templates/resource-ordering.md" + } + ] + }, + { + "title": "Parameters", + "description": "Prompt the user for additional information about a workspace", + "path": "./templates/parameters.md" + }, + { + "title": "Variables", + "description": "Prompt the template administrator for additional information about a template", + "path": "./templates/variables.md" + }, + { + "title": "Workspace Tags", + "description": "Control provisioning using Workspace Tags and Parameters", + "path": "./templates/workspace-tags.md" + }, + { + "title": "Administering templates", + "description": "Configuration settings for template admins", + "path": "./templates/configuration.md", + "children": [ + { + "title": "General settings", + "description": "Configure name, display info, and update polices", + "path": "./templates/general-settings.md" + }, + { + "title": "Permissions", + "description": "Configure who can access a template", + "path": "./templates/permissions.md" + }, + { + "title": "Workspace Scheduling", + "description": "Configure when workspaces start, stop, and delete", + "path": "./templates/schedule.md" + } + ] + }, + { + "title": "Open in Coder", + "description": "Add an \"Open in Coder\" button to your repos", + "path": "./templates/open-in-coder.md", + "icon_path": "./images/icons/key.svg" + }, + { + "title": "Docker in workspaces", + "description": "Use Docker inside containerized templates", + "path": "./templates/docker-in-workspaces.md", + "icon_path": "./images/icons/docker.svg" + }, + { + "title": "Dev Containers", + "description": "Use Dev Containers in workspaces", + "path": "./templates/dev-containers.md", + "state": "alpha" + }, + { + "title": "Troubleshooting templates", + "description": "Fix common template problems", + "path": "./templates/troubleshooting.md" + }, + { + "title": "Process Logging", + "description": "Audit commands in workspaces with exectrace", + "path": "./templates/process-logging.md", + "state": "enterprise" + }, + { + "title": "Icons", + "description": "Coder includes icons for popular cloud providers and programming languages for you to use", + "path": "./templates/icons.md" + } + ] + }, + { + "title": "Workspaces", + "description": "Learn about Coder workspaces.", + "path": "./workspaces.md", + "icon_path": "./images/icons/layers.svg" + }, + { + "title": "IDEs", + "description": "Learn how to use your IDE of choice with Coder", + "path": "./ides.md", + "icon_path": "./images/icons/code.svg", + "children": [ + { + "title": "Web IDEs", + "description": "Learn how to configure web IDEs in your templates", + "path": "./ides/web-ides.md" + }, + { + "title": "JetBrains Gateway", + "description": "Learn how to configure JetBrains Gateway for your workspaces", + "path": "./ides/gateway.md" + }, + { + "title": "JetBrains Fleet", + "description": "Learn how to configure JetBrains Fleet for your workspaces", + "path": "./ides/fleet.md" + }, + { + "title": "Emacs", + "description": "Learn how to configure Emacs with TRAMP in Coder", + "path": "./ides/emacs-tramp.md" + }, + { + "title": "Remote Desktops", + "description": "Learn how to use Remote Desktops with Coder", + "path": "./ides/remote-desktops.md" + } + ] + }, + { + "title": "Networking", + "description": "Learn about networking in Coder", + "path": "./networking/index.md", + "icon_path": "./images/icons/networking.svg", + "children": [ + { + "title": "Port Forwarding", + "description": "Learn how to forward ports in Coder", + "path": "./networking/port-forwarding.md" + }, + { + "title": "STUN and NAT", + "description": "Learn how Coder establishes direct connections", + "path": "./networking/stun.md" + } + ] + }, + { + "title": "Dotfiles", + "description": "Learn how to personalize your workspace", + "path": "./dotfiles.md", + "icon_path": "./images/icons/art-pad.svg" + }, + { + "title": "Secrets", + "description": "Learn how to use secrets in your workspace", + "path": "./secrets.md", + "icon_path": "./images/icons/secrets.svg" + }, + { + "title": "Administration", + "description": "How to install and deploy Coder", + "path": "./admin/README.md", + "icon_path": "./images/icons/wrench.svg", + "children": [ + { + "title": "Authentication", + "description": "Learn how to set up authentication using GitHub or OpenID Connect", + "path": "./admin/auth.md", + "icon_path": "./images/icons/key.svg" + }, + { + "title": "Users", + "description": "Learn about user roles available in Coder and how to create and manage users", + "path": "./admin/users.md", + "icon_path": "./images/icons/users.svg" + }, + { + "title": "Groups", + "description": "Learn how to manage user groups", + "path": "./admin/groups.md", + "icon_path": "./images/icons/group.svg", + "state": "enterprise" + }, + { + "title": "RBAC", + "description": "Learn how to use the role based access control", + "path": "./admin/rbac.md", + "icon_path": "./images/icons/rbac.svg", + "state": "enterprise" + }, + { + "title": "Configuration", + "description": "Learn how to configure Coder", + "path": "./admin/configure.md", + "icon_path": "./images/icons/toggle_on.svg" + }, + { + "title": "External Auth", + "description": "Learn how connect Coder with external auth providers", + "path": "./admin/external-auth.md", + "icon_path": "./images/icons/git.svg" + }, + { + "title": "Upgrading", + "description": "Learn how to upgrade Coder", + "path": "./admin/upgrade.md", + "icon_path": "./images/icons/upgrade.svg" + }, + { + "title": "Automation", + "description": "Learn how to automate Coder with the CLI and API", + "path": "./admin/automation.md", + "icon_path": "./images/icons/plug.svg" + }, + { + "title": "Scaling Coder", + "description": "Learn how to use load testing tools", + "path": "./admin/scaling/scale-testing.md", + "icon_path": "./images/icons/scale.svg", + "children": [ + { + "title": "Scaling Utility", + "path": "./admin/scaling/scale-utility.md" + } + ] + }, + { + "title": "External Provisioners", + "description": "Run provisioners isolated from the Coder server", + "path": "./admin/provisioners.md", + "icon_path": "./images/icons/queue.svg", + "state": "enterprise" + }, + { + "title": "Workspace Proxies", + "description": "Run geo distributed workspace proxies", + "path": "./admin/workspace-proxies.md", + "icon_path": "./images/icons/networking.svg", + "state": "enterprise" + }, + { + "title": "Application Logs", + "description": "Learn how to use Application Logs in your Coder deployment", + "path": "./admin/app-logs.md", + "icon_path": "./images/icons/notes.svg" + }, + { + "title": "Audit Logs", + "description": "Learn how to use Audit Logs in your Coder deployment", + "path": "./admin/audit-logs.md", + "icon_path": "./images/icons/radar.svg", + "state": "enterprise" + }, + { + "title": "Quotas", + "description": "Learn how to use Workspace Quotas in Coder", + "path": "./admin/quotas.md", + "icon_path": "./images/icons/dollar.svg", + "state": "enterprise" + }, + { + "title": "High Availability", + "description": "Learn how to configure Coder for High Availability", + "path": "./admin/high-availability.md", + "icon_path": "./images/icons/hydra.svg", + "state": "enterprise" + }, + { + "title": "Prometheus", + "description": "Learn how to collect Prometheus metrics", + "path": "./admin/prometheus.md", + "icon_path": "./images/icons/speed.svg" + }, + { + "title": "Appearance", + "description": "Learn how to configure the appearance of Coder", + "path": "./admin/appearance.md", + "icon_path": "./images/icons/info.svg", + "state": "enterprise" + }, + { + "title": "Telemetry", + "description": "Learn what usage telemetry Coder collects", + "path": "./admin/telemetry.md", + "icon_path": "./images/icons/science.svg" + }, + { + "title": "Database Encryption", + "description": "Learn how to encrypt sensitive data at rest in Coder", + "path": "./admin/encryption.md", + "icon_path": "./images/icons/lock.svg", + "state": "enterprise" + }, + { + "title": "Deployment Health", + "description": "Learn how to monitor the health of your Coder deployment", + "path": "./admin/healthcheck.md", + "icon_path": "./images/icons/health.svg" + } + ] + }, + { + "title": "Enterprise", + "description": "Learn how to enable Enterprise features", + "path": "./enterprise.md", + "icon_path": "./images/icons/group.svg" + }, + { + "title": "Contributing", + "description": "Learn how to contribute to Coder", + "path": "./CONTRIBUTING.md", + "icon_path": "./images/icons/contributing.svg", + "children": [ + { + "title": "Code of Conduct", + "description": "See the code of conduct for contributing to Coder", + "path": "./contributing/CODE_OF_CONDUCT.md" + }, + { + "title": "Feature stages", + "description": "Policies for Alpha and Experimental features.", + "path": "./contributing/feature-stages.md" + }, + { + "title": "Documentation", + "description": "Our style guide for use when authoring documentation", + "path": "./contributing/documentation.md" + }, + { + "title": "Security", + "description": "How to report vulnerabilities in Coder", + "path": "./contributing/SECURITY.md" + }, + { + "title": "Frontend", + "description": "Our guide for frontend development", + "path": "./contributing/frontend.md" + } + ] + }, + { + "title": "Reference", + "description": "Reference", + "path": "./reference/README.md", + "icon_path": "./images/icons/notes.svg", + "children": [ + { + "title": "REST API", + "description": "Learn how to use Coderd API", + "path": "./reference/api/README.md", + "icon_path": "./images/icons/api.svg", + "children": [ + { + "title": "General", + "path": "./reference/api/general.md" + }, + { + "title": "Agents", + "path": "./reference/api/agents.md" + }, + { + "title": "Applications", + "path": "./reference/api/applications.md" + }, + { + "title": "Audit", + "path": "./reference/api/audit.md" + }, + { + "title": "Authentication", + "path": "./reference/api/authentication.md" + }, + { + "title": "Authorization", + "path": "./reference/api/authorization.md" + }, + { + "title": "Builds", + "path": "./reference/api/builds.md" + }, + { + "title": "Debug", + "path": "./reference/api/debug.md" + }, + { + "title": "Enterprise", + "path": "./reference/api/enterprise.md" + }, + { + "title": "Files", + "path": "./reference/api/files.md" + }, + { + "title": "Git", + "path": "./reference/api/git.md" + }, + { + "title": "Insights", + "path": "./reference/api/insights.md" + }, + { + "title": "Members", + "path": "./reference/api/members.md" + }, + { + "title": "Organizations", + "path": "./reference/api/organizations.md" + }, + { + "title": "PortSharing", + "path": "./reference/api/portsharing.md" + }, + { + "title": "Schemas", + "path": "./reference/api/schemas.md" + }, + { + "title": "Templates", + "path": "./reference/api/templates.md" + }, + { + "title": "Users", + "path": "./reference/api/users.md" + }, + { + "title": "WorkspaceProxies", + "path": "./reference/api/workspaceproxies.md" + }, + { + "title": "Workspaces", + "path": "./reference/api/workspaces.md" + } + ] + }, + { + "title": "Command Line", + "description": "Learn how to use Coder CLI", + "path": "./reference/cli/README.md", + "icon_path": "./images/icons/terminal.svg", + "children": [ + { + "title": "autoupdate", + "description": "Toggle auto-update policy for a workspace", + "path": "reference/cli/autoupdate.md" + }, + { + "title": "coder", + "path": "reference/cli/README.md" + }, + { + "title": "config-ssh", + "description": "Add an SSH Host entry for your workspaces \"ssh coder.workspace\"", + "path": "reference/cli/config-ssh.md" + }, + { + "title": "create", + "description": "Create a workspace", + "path": "reference/cli/create.md" + }, + { + "title": "delete", + "description": "Delete a workspace", + "path": "reference/cli/delete.md" + }, + { + "title": "dotfiles", + "description": "Personalize your workspace by applying a canonical dotfiles repository", + "path": "reference/cli/dotfiles.md" + }, + { + "title": "external-auth", + "description": "Manage external authentication", + "path": "reference/cli/external-auth.md" + }, + { + "title": "external-auth access-token", + "description": "Print auth for an external provider", + "path": "reference/cli/external-auth_access-token.md" + }, + { + "title": "favorite", + "description": "Add a workspace to your favorites", + "path": "reference/cli/favorite.md" + }, + { + "title": "features", + "description": "List Enterprise features", + "path": "reference/cli/features.md" + }, + { + "title": "features list", + "path": "reference/cli/features_list.md" + }, + { + "title": "groups", + "description": "Manage groups", + "path": "reference/cli/groups.md" + }, + { + "title": "groups create", + "description": "Create a user group", + "path": "reference/cli/groups_create.md" + }, + { + "title": "groups delete", + "description": "Delete a user group", + "path": "reference/cli/groups_delete.md" + }, + { + "title": "groups edit", + "description": "Edit a user group", + "path": "reference/cli/groups_edit.md" + }, + { + "title": "groups list", + "description": "List user groups", + "path": "reference/cli/groups_list.md" + }, + { + "title": "licenses", + "description": "Add, delete, and list licenses", + "path": "reference/cli/licenses.md" + }, + { + "title": "licenses add", + "description": "Add license to Coder deployment", + "path": "reference/cli/licenses_add.md" + }, + { + "title": "licenses delete", + "description": "Delete license by ID", + "path": "reference/cli/licenses_delete.md" + }, + { + "title": "licenses list", + "description": "List licenses (including expired)", + "path": "reference/cli/licenses_list.md" + }, + { + "title": "list", + "description": "List workspaces", + "path": "reference/cli/list.md" + }, + { + "title": "login", + "description": "Authenticate with Coder deployment", + "path": "reference/cli/login.md" + }, + { + "title": "logout", + "description": "Unauthenticate your local session", + "path": "reference/cli/logout.md" + }, + { + "title": "netcheck", + "description": "Print network debug information for DERP and STUN", + "path": "reference/cli/netcheck.md" + }, + { + "title": "notifications", + "description": "Manage Coder notifications", + "path": "reference/cli/notifications.md" + }, + { + "title": "notifications pause", + "description": "Pause notifications", + "path": "reference/cli/notifications_pause.md" + }, + { + "title": "notifications resume", + "description": "Resume notifications", + "path": "reference/cli/notifications_resume.md" + }, + { + "title": "open", + "description": "Open a workspace", + "path": "reference/cli/open.md" + }, + { + "title": "open vscode", + "description": "Open a workspace in VS Code Desktop", + "path": "reference/cli/open_vscode.md" + }, + { + "title": "ping", + "description": "Ping a workspace", + "path": "reference/cli/ping.md" + }, + { + "title": "port-forward", + "description": "Forward ports from a workspace to the local machine. For reverse port forwarding, use \"coder ssh -R\".", + "path": "reference/cli/port-forward.md" + }, + { + "title": "provisionerd", + "description": "Manage provisioner daemons", + "path": "reference/cli/provisionerd.md" + }, + { + "title": "provisionerd start", + "description": "Run a provisioner daemon", + "path": "reference/cli/provisionerd_start.md" + }, + { + "title": "publickey", + "description": "Output your Coder public key used for Git operations", + "path": "reference/cli/publickey.md" + }, + { + "title": "rename", + "description": "Rename a workspace", + "path": "reference/cli/rename.md" + }, + { + "title": "reset-password", + "description": "Directly connect to the database to reset a user's password", + "path": "reference/cli/reset-password.md" + }, + { + "title": "restart", + "description": "Restart a workspace", + "path": "reference/cli/restart.md" + }, + { + "title": "schedule", + "description": "Schedule automated start and stop times for workspaces", + "path": "reference/cli/schedule.md" + }, + { + "title": "schedule override-stop", + "description": "Override the stop time of a currently running workspace instance.", + "path": "reference/cli/schedule_override-stop.md" + }, + { + "title": "schedule show", + "description": "Show workspace schedules", + "path": "reference/cli/schedule_show.md" + }, + { + "title": "schedule start", + "description": "Edit workspace start schedule", + "path": "reference/cli/schedule_start.md" + }, + { + "title": "schedule stop", + "description": "Edit workspace stop schedule", + "path": "reference/cli/schedule_stop.md" + }, + { + "title": "server", + "description": "Start a Coder server", + "path": "reference/cli/server.md" + }, + { + "title": "server create-admin-user", + "description": "Create a new admin user with the given username, email and password and adds it to every organization.", + "path": "reference/cli/server_create-admin-user.md" + }, + { + "title": "server dbcrypt", + "description": "Manage database encryption.", + "path": "reference/cli/server_dbcrypt.md" + }, + { + "title": "server dbcrypt decrypt", + "description": "Decrypt a previously encrypted database.", + "path": "reference/cli/server_dbcrypt_decrypt.md" + }, + { + "title": "server dbcrypt delete", + "description": "Delete all encrypted data from the database. THIS IS A DESTRUCTIVE OPERATION.", + "path": "reference/cli/server_dbcrypt_delete.md" + }, + { + "title": "server dbcrypt rotate", + "description": "Rotate database encryption keys.", + "path": "reference/cli/server_dbcrypt_rotate.md" + }, + { + "title": "server postgres-builtin-serve", + "description": "Run the built-in PostgreSQL deployment.", + "path": "reference/cli/server_postgres-builtin-serve.md" + }, + { + "title": "server postgres-builtin-url", + "description": "Output the connection URL for the built-in PostgreSQL deployment.", + "path": "reference/cli/server_postgres-builtin-url.md" + }, + { + "title": "show", + "description": "Display details of a workspace's resources and agents", + "path": "reference/cli/show.md" + }, + { + "title": "speedtest", + "description": "Run upload and download tests from your machine to a workspace", + "path": "reference/cli/speedtest.md" + }, + { + "title": "ssh", + "description": "Start a shell into a workspace", + "path": "reference/cli/ssh.md" + }, + { + "title": "start", + "description": "Start a workspace", + "path": "reference/cli/start.md" + }, + { + "title": "stat", + "description": "Show resource usage for the current workspace.", + "path": "reference/cli/stat.md" + }, + { + "title": "stat cpu", + "description": "Show CPU usage, in cores.", + "path": "reference/cli/stat_cpu.md" + }, + { + "title": "stat disk", + "description": "Show disk usage, in gigabytes.", + "path": "reference/cli/stat_disk.md" + }, + { + "title": "stat mem", + "description": "Show memory usage, in gigabytes.", + "path": "reference/cli/stat_mem.md" + }, + { + "title": "state", + "description": "Manually manage Terraform state to fix broken workspaces", + "path": "reference/cli/state.md" + }, + { + "title": "state pull", + "description": "Pull a Terraform state file from a workspace.", + "path": "reference/cli/state_pull.md" + }, + { + "title": "state push", + "description": "Push a Terraform state file to a workspace.", + "path": "reference/cli/state_push.md" + }, + { + "title": "stop", + "description": "Stop a workspace", + "path": "reference/cli/stop.md" + }, + { + "title": "support", + "description": "Commands for troubleshooting issues with a Coder deployment.", + "path": "reference/cli/support.md" + }, + { + "title": "support bundle", + "description": "Generate a support bundle to troubleshoot issues connecting to a workspace.", + "path": "reference/cli/support_bundle.md" + }, + { + "title": "templates", + "description": "Manage templates", + "path": "reference/cli/templates.md" + }, + { + "title": "templates archive", + "description": "Archive unused or failed template versions from a given template(s)", + "path": "reference/cli/templates_archive.md" + }, + { + "title": "templates create", + "description": "DEPRECATED: Create a template from the current directory or as specified by flag", + "path": "reference/cli/templates_create.md" + }, + { + "title": "templates delete", + "description": "Delete templates", + "path": "reference/cli/templates_delete.md" + }, + { + "title": "templates edit", + "description": "Edit the metadata of a template by name.", + "path": "reference/cli/templates_edit.md" + }, + { + "title": "templates init", + "description": "Get started with a templated template.", + "path": "reference/cli/templates_init.md" + }, + { + "title": "templates list", + "description": "List all the templates available for the organization", + "path": "reference/cli/templates_list.md" + }, + { + "title": "templates pull", + "description": "Download the active, latest, or specified version of a template to a path.", + "path": "reference/cli/templates_pull.md" + }, + { + "title": "templates push", + "description": "Create or update a template from the current directory or as specified by flag", + "path": "reference/cli/templates_push.md" + }, + { + "title": "templates versions", + "description": "Manage different versions of the specified template", + "path": "reference/cli/templates_versions.md" + }, + { + "title": "templates versions archive", + "description": "Archive a template version(s).", + "path": "reference/cli/templates_versions_archive.md" + }, + { + "title": "templates versions list", + "description": "List all the versions of the specified template", + "path": "reference/cli/templates_versions_list.md" + }, + { + "title": "templates versions unarchive", + "description": "Unarchive a template version(s).", + "path": "reference/cli/templates_versions_unarchive.md" + }, + { + "title": "tokens", + "description": "Manage personal access tokens", + "path": "reference/cli/tokens.md" + }, + { + "title": "tokens create", + "description": "Create a token", + "path": "reference/cli/tokens_create.md" + }, + { + "title": "tokens list", + "description": "List tokens", + "path": "reference/cli/tokens_list.md" + }, + { + "title": "tokens remove", + "description": "Delete a token", + "path": "reference/cli/tokens_remove.md" + }, + { + "title": "unfavorite", + "description": "Remove a workspace from your favorites", + "path": "reference/cli/unfavorite.md" + }, + { + "title": "update", + "description": "Will update and start a given workspace if it is out of date", + "path": "reference/cli/update.md" + }, + { + "title": "users", + "description": "Manage users", + "path": "reference/cli/users.md" + }, + { + "title": "users activate", + "description": "Update a user's status to 'active'. Active users can fully interact with the platform", + "path": "reference/cli/users_activate.md" + }, + { + "title": "users create", + "path": "reference/cli/users_create.md" + }, + { + "title": "users delete", + "description": "Delete a user by username or user_id.", + "path": "reference/cli/users_delete.md" + }, + { + "title": "users list", + "path": "reference/cli/users_list.md" + }, + { + "title": "users show", + "description": "Show a single user. Use 'me' to indicate the currently authenticated user.", + "path": "reference/cli/users_show.md" + }, + { + "title": "users suspend", + "description": "Update a user's status to 'suspended'. A suspended user cannot log into the platform", + "path": "reference/cli/users_suspend.md" + }, + { + "title": "version", + "description": "Show coder version", + "path": "reference/cli/version.md" + }, + { + "title": "whoami", + "description": "Fetch authenticated user info for Coder deployment", + "path": "reference/cli/whoami.md" + } + ] + } + ] + }, + { + "title": "Security", + "description": "Security advisories", + "path": "./security/index.md", + "icon_path": "./images/icons/security.svg", + "children": [ + { + "title": "API tokens of deleted users not invalidated", + "description": "Fixed in v0.23.0 (Apr 25, 2023)", + "path": "./security/0001_user_apikeys_invalidation.md" + } + ] + }, + { + "title": "FAQs", + "description": "Frequently asked questions", + "path": "./faqs.md", + "icon_path": "./images/icons/info.svg" + }, + { + "title": "Guides", + "description": "Employee-authored tutorials", + "path": "./guides/index.md", + "icon_path": "./images/icons/notes.svg", + "children": [ + { + "title": "Generate a Support Bundle", + "description": "Generate and upload a Support Bundle to Coder Support", + "path": "./guides/support-bundle.md" + }, + { + "title": "Configuring Okta", + "description": "Custom claims/scopes with Okta for group/role sync", + "path": "./guides/configuring-okta.md" + }, + { + "title": "Google to AWS Federation", + "description": "Federating a Google Cloud service account to AWS", + "path": "./guides/gcp-to-aws.md" + }, + { + "title": "JFrog Artifactory Integration", + "description": "Integrate Coder with JFrog Artifactory", + "path": "./guides/artifactory-integration.md" + }, + { + "title": "Island Enterprise Browser Integration", + "description": "Integrate Coder with Island's Enterprise Browser", + "path": "./guides/island-integration.md" + }, + { + "title": "Template ImagePullSecrets", + "description": "Creating ImagePullSecrets for private registries", + "path": "./guides/image-pull-secret.md" + }, + { + "title": "Postgres SSL", + "description": "Configure Coder to connect to Postgres over SSL", + "path": "./guides/postgres-ssl.md" + }, + { + "title": "Azure Federation", + "description": "Federating Coder to Azure", + "path": "./guides/azure-federation.md" + }, + { + "title": "Scanning Coder Workspaces with JFrog Xray", + "description": "Integrate Coder with JFrog Xray", + "path": "./guides/xray-integration.md" + }, + { + "title": "Cloning Git Repositories", + "description": "Automatically clone Git repositories into your workspace", + "path": "./guides/cloning-git-repositories.md" + } + ] + } + ] } diff --git a/docs/reference/api/agents.md b/docs/reference/api/agents.md index e32fb0ac10..a7bc86190e 100644 --- a/docs/reference/api/agents.md +++ b/docs/reference/api/agents.md @@ -38,8 +38,8 @@ curl -X POST http://coder-server:8080/api/v2/workspaceagents/aws-instance-identi ```json { - "document": "string", - "signature": "string" + "document": "string", + "signature": "string" } ``` @@ -55,7 +55,7 @@ curl -X POST http://coder-server:8080/api/v2/workspaceagents/aws-instance-identi ```json { - "session_token": "string" + "session_token": "string" } ``` @@ -85,8 +85,8 @@ curl -X POST http://coder-server:8080/api/v2/workspaceagents/azure-instance-iden ```json { - "encoding": "string", - "signature": "string" + "encoding": "string", + "signature": "string" } ``` @@ -102,7 +102,7 @@ curl -X POST http://coder-server:8080/api/v2/workspaceagents/azure-instance-iden ```json { - "session_token": "string" + "session_token": "string" } ``` @@ -132,7 +132,7 @@ curl -X POST http://coder-server:8080/api/v2/workspaceagents/google-instance-ide ```json { - "json_web_token": "string" + "json_web_token": "string" } ``` @@ -148,7 +148,7 @@ curl -X POST http://coder-server:8080/api/v2/workspaceagents/google-instance-ide ```json { - "session_token": "string" + "session_token": "string" } ``` @@ -187,12 +187,12 @@ curl -X GET http://coder-server:8080/api/v2/workspaceagents/me/external-auth?mat ```json { - "access_token": "string", - "password": "string", - "token_extra": {}, - "type": "string", - "url": "string", - "username": "string" + "access_token": "string", + "password": "string", + "token_extra": {}, + "type": "string", + "url": "string", + "username": "string" } ``` @@ -231,12 +231,12 @@ curl -X GET http://coder-server:8080/api/v2/workspaceagents/me/gitauth?match=str ```json { - "access_token": "string", - "password": "string", - "token_extra": {}, - "type": "string", - "url": "string", - "username": "string" + "access_token": "string", + "password": "string", + "token_extra": {}, + "type": "string", + "url": "string", + "username": "string" } ``` @@ -267,8 +267,8 @@ curl -X GET http://coder-server:8080/api/v2/workspaceagents/me/gitsshkey \ ```json { - "private_key": "string", - "public_key": "string" + "private_key": "string", + "public_key": "string" } ``` @@ -298,9 +298,9 @@ curl -X POST http://coder-server:8080/api/v2/workspaceagents/me/log-source \ ```json { - "display_name": "string", - "icon": "string", - "id": "string" + "display_name": "string", + "icon": "string", + "id": "string" } ``` @@ -316,11 +316,11 @@ curl -X POST http://coder-server:8080/api/v2/workspaceagents/me/log-source \ ```json { - "created_at": "2019-08-24T14:15:22Z", - "display_name": "string", - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" + "created_at": "2019-08-24T14:15:22Z", + "display_name": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" } ``` @@ -350,14 +350,14 @@ curl -X PATCH http://coder-server:8080/api/v2/workspaceagents/me/logs \ ```json { - "log_source_id": "string", - "logs": [ - { - "created_at": "string", - "level": "trace", - "output": "string" - } - ] + "log_source_id": "string", + "logs": [ + { + "created_at": "string", + "level": "trace", + "output": "string" + } + ] } ``` @@ -373,14 +373,14 @@ curl -X PATCH http://coder-server:8080/api/v2/workspaceagents/me/logs \ ```json { - "detail": "string", - "message": "string", - "validations": [ - { - "detail": "string", - "field": "string" - } - ] + "detail": "string", + "message": "string", + "validations": [ + { + "detail": "string", + "field": "string" + } + ] } ``` @@ -417,91 +417,91 @@ curl -X GET http://coder-server:8080/api/v2/workspaceagents/{workspaceagent} \ ```json { - "api_version": "string", - "apps": [ - { - "command": "string", - "display_name": "string", - "external": true, - "health": "disabled", - "healthcheck": { - "interval": 0, - "threshold": 0, - "url": "string" - }, - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "sharing_level": "owner", - "slug": "string", - "subdomain": true, - "subdomain_name": "string", - "url": "string" - } - ], - "architecture": "string", - "connection_timeout_seconds": 0, - "created_at": "2019-08-24T14:15:22Z", - "directory": "string", - "disconnected_at": "2019-08-24T14:15:22Z", - "display_apps": ["vscode"], - "environment_variables": { - "property1": "string", - "property2": "string" - }, - "expanded_directory": "string", - "first_connected_at": "2019-08-24T14:15:22Z", - "health": { - "healthy": false, - "reason": "agent has lost connection" - }, - "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 - } - }, - "lifecycle_state": "created", - "log_sources": [ - { - "created_at": "2019-08-24T14:15:22Z", - "display_name": "string", - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" - } - ], - "logs_length": 0, - "logs_overflowed": true, - "name": "string", - "operating_system": "string", - "ready_at": "2019-08-24T14:15:22Z", - "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", - "scripts": [ - { - "cron": "string", - "log_path": "string", - "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", - "run_on_start": true, - "run_on_stop": true, - "script": "string", - "start_blocks_login": true, - "timeout": 0 - } - ], - "started_at": "2019-08-24T14:15:22Z", - "startup_script_behavior": "blocking", - "status": "connecting", - "subsystems": ["envbox"], - "troubleshooting_url": "string", - "updated_at": "2019-08-24T14:15:22Z", - "version": "string" + "api_version": "string", + "apps": [ + { + "command": "string", + "display_name": "string", + "external": true, + "health": "disabled", + "healthcheck": { + "interval": 0, + "threshold": 0, + "url": "string" + }, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "sharing_level": "owner", + "slug": "string", + "subdomain": true, + "subdomain_name": "string", + "url": "string" + } + ], + "architecture": "string", + "connection_timeout_seconds": 0, + "created_at": "2019-08-24T14:15:22Z", + "directory": "string", + "disconnected_at": "2019-08-24T14:15:22Z", + "display_apps": ["vscode"], + "environment_variables": { + "property1": "string", + "property2": "string" + }, + "expanded_directory": "string", + "first_connected_at": "2019-08-24T14:15:22Z", + "health": { + "healthy": false, + "reason": "agent has lost connection" + }, + "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 + } + }, + "lifecycle_state": "created", + "log_sources": [ + { + "created_at": "2019-08-24T14:15:22Z", + "display_name": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" + } + ], + "logs_length": 0, + "logs_overflowed": true, + "name": "string", + "operating_system": "string", + "ready_at": "2019-08-24T14:15:22Z", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", + "scripts": [ + { + "cron": "string", + "log_path": "string", + "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", + "run_on_start": true, + "run_on_stop": true, + "script": "string", + "start_blocks_login": true, + "timeout": 0 + } + ], + "started_at": "2019-08-24T14:15:22Z", + "startup_script_behavior": "blocking", + "status": "connecting", + "subsystems": ["envbox"], + "troubleshooting_url": "string", + "updated_at": "2019-08-24T14:15:22Z", + "version": "string" } ``` @@ -538,67 +538,67 @@ curl -X GET http://coder-server:8080/api/v2/workspaceagents/{workspaceagent}/con ```json { - "derp_force_websockets": true, - "derp_map": { - "homeParams": { - "regionScore": { - "property1": 0, - "property2": 0 - } - }, - "omitDefaultRegions": true, - "regions": { - "property1": { - "avoid": true, - "embeddedRelay": true, - "nodes": [ - { - "canPort80": true, - "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": [ - { - "canPort80": true, - "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" - } - } - }, - "disable_direct_connections": true + "derp_force_websockets": true, + "derp_map": { + "homeParams": { + "regionScore": { + "property1": 0, + "property2": 0 + } + }, + "omitDefaultRegions": true, + "regions": { + "property1": { + "avoid": true, + "embeddedRelay": true, + "nodes": [ + { + "canPort80": true, + "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": [ + { + "canPort80": true, + "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" + } + } + }, + "disable_direct_connections": true } ``` @@ -661,13 +661,13 @@ curl -X GET http://coder-server:8080/api/v2/workspaceagents/{workspaceagent}/lis ```json { - "ports": [ - { - "network": "string", - "port": 0, - "process_name": "string" - } - ] + "ports": [ + { + "network": "string", + "port": 0, + "process_name": "string" + } + ] } ``` @@ -708,13 +708,13 @@ curl -X GET http://coder-server:8080/api/v2/workspaceagents/{workspaceagent}/log ```json [ - { - "created_at": "2019-08-24T14:15:22Z", - "id": 0, - "level": "trace", - "output": "string", - "source_id": "ae50a35c-df42-4eff-ba26-f8bc28d2af81" - } + { + "created_at": "2019-08-24T14:15:22Z", + "id": 0, + "level": "trace", + "output": "string", + "source_id": "ae50a35c-df42-4eff-ba26-f8bc28d2af81" + } ] ``` @@ -804,13 +804,13 @@ curl -X GET http://coder-server:8080/api/v2/workspaceagents/{workspaceagent}/sta ```json [ - { - "created_at": "2019-08-24T14:15:22Z", - "id": 0, - "level": "trace", - "output": "string", - "source_id": "ae50a35c-df42-4eff-ba26-f8bc28d2af81" - } + { + "created_at": "2019-08-24T14:15:22Z", + "id": 0, + "level": "trace", + "output": "string", + "source_id": "ae50a35c-df42-4eff-ba26-f8bc28d2af81" + } ] ``` diff --git a/docs/reference/api/applications.md b/docs/reference/api/applications.md index 2aa3623122..ce84a41438 100644 --- a/docs/reference/api/applications.md +++ b/docs/reference/api/applications.md @@ -45,7 +45,7 @@ curl -X GET http://coder-server:8080/api/v2/applications/host \ ```json { - "host": "string" + "host": "string" } ``` diff --git a/docs/reference/api/audit.md b/docs/reference/api/audit.md index adf2780685..1cec64e9f8 100644 --- a/docs/reference/api/audit.md +++ b/docs/reference/api/audit.md @@ -27,66 +27,66 @@ curl -X GET http://coder-server:8080/api/v2/audit?limit=0 \ ```json { - "audit_logs": [ - { - "action": "create", - "additional_fields": [0], - "description": "string", - "diff": { - "property1": { - "new": null, - "old": null, - "secret": true - }, - "property2": { - "new": null, - "old": null, - "secret": true - } - }, - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "ip": "string", - "is_deleted": true, - "organization": { - "display_name": "string", - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "name": "string" - }, - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "request_id": "266ea41d-adf5-480b-af50-15b940c2b846", - "resource_icon": "string", - "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", - "resource_link": "string", - "resource_target": "string", - "resource_type": "template", - "status_code": 0, - "time": "2019-08-24T14:15:22Z", - "user": { - "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", - "login_type": "", - "name": "string", - "organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "roles": [ - { - "display_name": "string", - "name": "string", - "organization_id": "string" - } - ], - "status": "active", - "theme_preference": "string", - "updated_at": "2019-08-24T14:15:22Z", - "username": "string" - }, - "user_agent": "string" - } - ], - "count": 0 + "audit_logs": [ + { + "action": "create", + "additional_fields": [0], + "description": "string", + "diff": { + "property1": { + "new": null, + "old": null, + "secret": true + }, + "property2": { + "new": null, + "old": null, + "secret": true + } + }, + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "ip": "string", + "is_deleted": true, + "organization": { + "display_name": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "string" + }, + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "request_id": "266ea41d-adf5-480b-af50-15b940c2b846", + "resource_icon": "string", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", + "resource_link": "string", + "resource_target": "string", + "resource_type": "template", + "status_code": 0, + "time": "2019-08-24T14:15:22Z", + "user": { + "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", + "login_type": "", + "name": "string", + "organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "roles": [ + { + "display_name": "string", + "name": "string", + "organization_id": "string" + } + ], + "status": "active", + "theme_preference": "string", + "updated_at": "2019-08-24T14:15:22Z", + "username": "string" + }, + "user_agent": "string" + } + ], + "count": 0 } ``` diff --git a/docs/reference/api/authorization.md b/docs/reference/api/authorization.md index 19b6f75821..537d7e6944 100644 --- a/docs/reference/api/authorization.md +++ b/docs/reference/api/authorization.md @@ -18,28 +18,28 @@ curl -X POST http://coder-server:8080/api/v2/authcheck \ ```json { - "checks": { - "property1": { - "action": "create", - "object": { - "any_org": true, - "organization_id": "string", - "owner_id": "string", - "resource_id": "string", - "resource_type": "*" - } - }, - "property2": { - "action": "create", - "object": { - "any_org": true, - "organization_id": "string", - "owner_id": "string", - "resource_id": "string", - "resource_type": "*" - } - } - } + "checks": { + "property1": { + "action": "create", + "object": { + "any_org": true, + "organization_id": "string", + "owner_id": "string", + "resource_id": "string", + "resource_type": "*" + } + }, + "property2": { + "action": "create", + "object": { + "any_org": true, + "organization_id": "string", + "owner_id": "string", + "resource_id": "string", + "resource_type": "*" + } + } + } } ``` @@ -55,8 +55,8 @@ curl -X POST http://coder-server:8080/api/v2/authcheck \ ```json { - "property1": true, - "property2": true + "property1": true, + "property2": true } ``` @@ -85,8 +85,8 @@ curl -X POST http://coder-server:8080/api/v2/users/login \ ```json { - "email": "user@example.com", - "password": "string" + "email": "user@example.com", + "password": "string" } ``` @@ -102,7 +102,7 @@ curl -X POST http://coder-server:8080/api/v2/users/login \ ```json { - "session_token": "string" + "session_token": "string" } ``` @@ -130,8 +130,8 @@ curl -X POST http://coder-server:8080/api/v2/users/{user}/convert-login \ ```json { - "password": "string", - "to_type": "" + "password": "string", + "to_type": "" } ``` @@ -148,10 +148,10 @@ curl -X POST http://coder-server:8080/api/v2/users/{user}/convert-login \ ```json { - "expires_at": "2019-08-24T14:15:22Z", - "state_string": "string", - "to_type": "", - "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5" + "expires_at": "2019-08-24T14:15:22Z", + "state_string": "string", + "to_type": "", + "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5" } ``` diff --git a/docs/reference/api/builds.md b/docs/reference/api/builds.md index 8cad5b3a73..85731a8f63 100644 --- a/docs/reference/api/builds.md +++ b/docs/reference/api/builds.md @@ -27,152 +27,152 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/workspace/{workspacenam ```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", - "error_code": "REQUIRED_TEMPLATE_VARIABLES", - "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "queue_position": 0, - "queue_size": 0, - "started_at": "2019-08-24T14:15:22Z", - "status": "pending", - "tags": { - "property1": "string", - "property2": "string" - }, - "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" - }, - "max_deadline": "2019-08-24T14:15:22Z", - "reason": "initiator", - "resources": [ - { - "agents": [ - { - "api_version": "string", - "apps": [ - { - "command": "string", - "display_name": "string", - "external": true, - "health": "disabled", - "healthcheck": { - "interval": 0, - "threshold": 0, - "url": "string" - }, - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "sharing_level": "owner", - "slug": "string", - "subdomain": true, - "subdomain_name": "string", - "url": "string" - } - ], - "architecture": "string", - "connection_timeout_seconds": 0, - "created_at": "2019-08-24T14:15:22Z", - "directory": "string", - "disconnected_at": "2019-08-24T14:15:22Z", - "display_apps": ["vscode"], - "environment_variables": { - "property1": "string", - "property2": "string" - }, - "expanded_directory": "string", - "first_connected_at": "2019-08-24T14:15:22Z", - "health": { - "healthy": false, - "reason": "agent has lost connection" - }, - "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 - } - }, - "lifecycle_state": "created", - "log_sources": [ - { - "created_at": "2019-08-24T14:15:22Z", - "display_name": "string", - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" - } - ], - "logs_length": 0, - "logs_overflowed": true, - "name": "string", - "operating_system": "string", - "ready_at": "2019-08-24T14:15:22Z", - "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", - "scripts": [ - { - "cron": "string", - "log_path": "string", - "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", - "run_on_start": true, - "run_on_stop": true, - "script": "string", - "start_blocks_login": true, - "timeout": 0 - } - ], - "started_at": "2019-08-24T14:15:22Z", - "startup_script_behavior": "blocking", - "status": "connecting", - "subsystems": ["envbox"], - "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_avatar_url": "string", - "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7", - "workspace_owner_name": "string" + "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", + "error_code": "REQUIRED_TEMPLATE_VARIABLES", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "queue_position": 0, + "queue_size": 0, + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" + }, + "max_deadline": "2019-08-24T14:15:22Z", + "reason": "initiator", + "resources": [ + { + "agents": [ + { + "api_version": "string", + "apps": [ + { + "command": "string", + "display_name": "string", + "external": true, + "health": "disabled", + "healthcheck": { + "interval": 0, + "threshold": 0, + "url": "string" + }, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "sharing_level": "owner", + "slug": "string", + "subdomain": true, + "subdomain_name": "string", + "url": "string" + } + ], + "architecture": "string", + "connection_timeout_seconds": 0, + "created_at": "2019-08-24T14:15:22Z", + "directory": "string", + "disconnected_at": "2019-08-24T14:15:22Z", + "display_apps": ["vscode"], + "environment_variables": { + "property1": "string", + "property2": "string" + }, + "expanded_directory": "string", + "first_connected_at": "2019-08-24T14:15:22Z", + "health": { + "healthy": false, + "reason": "agent has lost connection" + }, + "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 + } + }, + "lifecycle_state": "created", + "log_sources": [ + { + "created_at": "2019-08-24T14:15:22Z", + "display_name": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" + } + ], + "logs_length": 0, + "logs_overflowed": true, + "name": "string", + "operating_system": "string", + "ready_at": "2019-08-24T14:15:22Z", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", + "scripts": [ + { + "cron": "string", + "log_path": "string", + "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", + "run_on_start": true, + "run_on_stop": true, + "script": "string", + "start_blocks_login": true, + "timeout": 0 + } + ], + "started_at": "2019-08-24T14:15:22Z", + "startup_script_behavior": "blocking", + "status": "connecting", + "subsystems": ["envbox"], + "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_avatar_url": "string", + "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7", + "workspace_owner_name": "string" } ``` @@ -209,152 +209,152 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild} \ ```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", - "error_code": "REQUIRED_TEMPLATE_VARIABLES", - "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "queue_position": 0, - "queue_size": 0, - "started_at": "2019-08-24T14:15:22Z", - "status": "pending", - "tags": { - "property1": "string", - "property2": "string" - }, - "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" - }, - "max_deadline": "2019-08-24T14:15:22Z", - "reason": "initiator", - "resources": [ - { - "agents": [ - { - "api_version": "string", - "apps": [ - { - "command": "string", - "display_name": "string", - "external": true, - "health": "disabled", - "healthcheck": { - "interval": 0, - "threshold": 0, - "url": "string" - }, - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "sharing_level": "owner", - "slug": "string", - "subdomain": true, - "subdomain_name": "string", - "url": "string" - } - ], - "architecture": "string", - "connection_timeout_seconds": 0, - "created_at": "2019-08-24T14:15:22Z", - "directory": "string", - "disconnected_at": "2019-08-24T14:15:22Z", - "display_apps": ["vscode"], - "environment_variables": { - "property1": "string", - "property2": "string" - }, - "expanded_directory": "string", - "first_connected_at": "2019-08-24T14:15:22Z", - "health": { - "healthy": false, - "reason": "agent has lost connection" - }, - "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 - } - }, - "lifecycle_state": "created", - "log_sources": [ - { - "created_at": "2019-08-24T14:15:22Z", - "display_name": "string", - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" - } - ], - "logs_length": 0, - "logs_overflowed": true, - "name": "string", - "operating_system": "string", - "ready_at": "2019-08-24T14:15:22Z", - "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", - "scripts": [ - { - "cron": "string", - "log_path": "string", - "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", - "run_on_start": true, - "run_on_stop": true, - "script": "string", - "start_blocks_login": true, - "timeout": 0 - } - ], - "started_at": "2019-08-24T14:15:22Z", - "startup_script_behavior": "blocking", - "status": "connecting", - "subsystems": ["envbox"], - "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_avatar_url": "string", - "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7", - "workspace_owner_name": "string" + "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", + "error_code": "REQUIRED_TEMPLATE_VARIABLES", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "queue_position": 0, + "queue_size": 0, + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" + }, + "max_deadline": "2019-08-24T14:15:22Z", + "reason": "initiator", + "resources": [ + { + "agents": [ + { + "api_version": "string", + "apps": [ + { + "command": "string", + "display_name": "string", + "external": true, + "health": "disabled", + "healthcheck": { + "interval": 0, + "threshold": 0, + "url": "string" + }, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "sharing_level": "owner", + "slug": "string", + "subdomain": true, + "subdomain_name": "string", + "url": "string" + } + ], + "architecture": "string", + "connection_timeout_seconds": 0, + "created_at": "2019-08-24T14:15:22Z", + "directory": "string", + "disconnected_at": "2019-08-24T14:15:22Z", + "display_apps": ["vscode"], + "environment_variables": { + "property1": "string", + "property2": "string" + }, + "expanded_directory": "string", + "first_connected_at": "2019-08-24T14:15:22Z", + "health": { + "healthy": false, + "reason": "agent has lost connection" + }, + "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 + } + }, + "lifecycle_state": "created", + "log_sources": [ + { + "created_at": "2019-08-24T14:15:22Z", + "display_name": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" + } + ], + "logs_length": 0, + "logs_overflowed": true, + "name": "string", + "operating_system": "string", + "ready_at": "2019-08-24T14:15:22Z", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", + "scripts": [ + { + "cron": "string", + "log_path": "string", + "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", + "run_on_start": true, + "run_on_stop": true, + "script": "string", + "start_blocks_login": true, + "timeout": 0 + } + ], + "started_at": "2019-08-24T14:15:22Z", + "startup_script_behavior": "blocking", + "status": "connecting", + "subsystems": ["envbox"], + "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_avatar_url": "string", + "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7", + "workspace_owner_name": "string" } ``` @@ -391,14 +391,14 @@ curl -X PATCH http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/c ```json { - "detail": "string", - "message": "string", - "validations": [ - { - "detail": "string", - "field": "string" - } - ] + "detail": "string", + "message": "string", + "validations": [ + { + "detail": "string", + "field": "string" + } + ] } ``` @@ -438,14 +438,14 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/log ```json [ - { - "created_at": "2019-08-24T14:15:22Z", - "id": 0, - "log_level": "trace", - "log_source": "provisioner_daemon", - "output": "string", - "stage": "string" - } + { + "created_at": "2019-08-24T14:15:22Z", + "id": 0, + "log_level": "trace", + "log_source": "provisioner_daemon", + "output": "string", + "stage": "string" + } ] ``` @@ -508,10 +508,10 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/par ```json [ - { - "name": "string", - "value": "string" - } + { + "name": "string", + "value": "string" + } ] ``` @@ -558,113 +558,113 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/res ```json [ - { - "agents": [ - { - "api_version": "string", - "apps": [ - { - "command": "string", - "display_name": "string", - "external": true, - "health": "disabled", - "healthcheck": { - "interval": 0, - "threshold": 0, - "url": "string" - }, - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "sharing_level": "owner", - "slug": "string", - "subdomain": true, - "subdomain_name": "string", - "url": "string" - } - ], - "architecture": "string", - "connection_timeout_seconds": 0, - "created_at": "2019-08-24T14:15:22Z", - "directory": "string", - "disconnected_at": "2019-08-24T14:15:22Z", - "display_apps": ["vscode"], - "environment_variables": { - "property1": "string", - "property2": "string" - }, - "expanded_directory": "string", - "first_connected_at": "2019-08-24T14:15:22Z", - "health": { - "healthy": false, - "reason": "agent has lost connection" - }, - "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 - } - }, - "lifecycle_state": "created", - "log_sources": [ - { - "created_at": "2019-08-24T14:15:22Z", - "display_name": "string", - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" - } - ], - "logs_length": 0, - "logs_overflowed": true, - "name": "string", - "operating_system": "string", - "ready_at": "2019-08-24T14:15:22Z", - "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", - "scripts": [ - { - "cron": "string", - "log_path": "string", - "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", - "run_on_start": true, - "run_on_stop": true, - "script": "string", - "start_blocks_login": true, - "timeout": 0 - } - ], - "started_at": "2019-08-24T14:15:22Z", - "startup_script_behavior": "blocking", - "status": "connecting", - "subsystems": ["envbox"], - "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" - } + { + "agents": [ + { + "api_version": "string", + "apps": [ + { + "command": "string", + "display_name": "string", + "external": true, + "health": "disabled", + "healthcheck": { + "interval": 0, + "threshold": 0, + "url": "string" + }, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "sharing_level": "owner", + "slug": "string", + "subdomain": true, + "subdomain_name": "string", + "url": "string" + } + ], + "architecture": "string", + "connection_timeout_seconds": 0, + "created_at": "2019-08-24T14:15:22Z", + "directory": "string", + "disconnected_at": "2019-08-24T14:15:22Z", + "display_apps": ["vscode"], + "environment_variables": { + "property1": "string", + "property2": "string" + }, + "expanded_directory": "string", + "first_connected_at": "2019-08-24T14:15:22Z", + "health": { + "healthy": false, + "reason": "agent has lost connection" + }, + "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 + } + }, + "lifecycle_state": "created", + "log_sources": [ + { + "created_at": "2019-08-24T14:15:22Z", + "display_name": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" + } + ], + "logs_length": 0, + "logs_overflowed": true, + "name": "string", + "operating_system": "string", + "ready_at": "2019-08-24T14:15:22Z", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", + "scripts": [ + { + "cron": "string", + "log_path": "string", + "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", + "run_on_start": true, + "run_on_stop": true, + "script": "string", + "start_blocks_login": true, + "timeout": 0 + } + ], + "started_at": "2019-08-24T14:15:22Z", + "startup_script_behavior": "blocking", + "status": "connecting", + "subsystems": ["envbox"], + "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" + } ] ``` @@ -819,152 +819,152 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/sta ```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", - "error_code": "REQUIRED_TEMPLATE_VARIABLES", - "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "queue_position": 0, - "queue_size": 0, - "started_at": "2019-08-24T14:15:22Z", - "status": "pending", - "tags": { - "property1": "string", - "property2": "string" - }, - "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" - }, - "max_deadline": "2019-08-24T14:15:22Z", - "reason": "initiator", - "resources": [ - { - "agents": [ - { - "api_version": "string", - "apps": [ - { - "command": "string", - "display_name": "string", - "external": true, - "health": "disabled", - "healthcheck": { - "interval": 0, - "threshold": 0, - "url": "string" - }, - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "sharing_level": "owner", - "slug": "string", - "subdomain": true, - "subdomain_name": "string", - "url": "string" - } - ], - "architecture": "string", - "connection_timeout_seconds": 0, - "created_at": "2019-08-24T14:15:22Z", - "directory": "string", - "disconnected_at": "2019-08-24T14:15:22Z", - "display_apps": ["vscode"], - "environment_variables": { - "property1": "string", - "property2": "string" - }, - "expanded_directory": "string", - "first_connected_at": "2019-08-24T14:15:22Z", - "health": { - "healthy": false, - "reason": "agent has lost connection" - }, - "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 - } - }, - "lifecycle_state": "created", - "log_sources": [ - { - "created_at": "2019-08-24T14:15:22Z", - "display_name": "string", - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" - } - ], - "logs_length": 0, - "logs_overflowed": true, - "name": "string", - "operating_system": "string", - "ready_at": "2019-08-24T14:15:22Z", - "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", - "scripts": [ - { - "cron": "string", - "log_path": "string", - "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", - "run_on_start": true, - "run_on_stop": true, - "script": "string", - "start_blocks_login": true, - "timeout": 0 - } - ], - "started_at": "2019-08-24T14:15:22Z", - "startup_script_behavior": "blocking", - "status": "connecting", - "subsystems": ["envbox"], - "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_avatar_url": "string", - "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7", - "workspace_owner_name": "string" + "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", + "error_code": "REQUIRED_TEMPLATE_VARIABLES", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "queue_position": 0, + "queue_size": 0, + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" + }, + "max_deadline": "2019-08-24T14:15:22Z", + "reason": "initiator", + "resources": [ + { + "agents": [ + { + "api_version": "string", + "apps": [ + { + "command": "string", + "display_name": "string", + "external": true, + "health": "disabled", + "healthcheck": { + "interval": 0, + "threshold": 0, + "url": "string" + }, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "sharing_level": "owner", + "slug": "string", + "subdomain": true, + "subdomain_name": "string", + "url": "string" + } + ], + "architecture": "string", + "connection_timeout_seconds": 0, + "created_at": "2019-08-24T14:15:22Z", + "directory": "string", + "disconnected_at": "2019-08-24T14:15:22Z", + "display_apps": ["vscode"], + "environment_variables": { + "property1": "string", + "property2": "string" + }, + "expanded_directory": "string", + "first_connected_at": "2019-08-24T14:15:22Z", + "health": { + "healthy": false, + "reason": "agent has lost connection" + }, + "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 + } + }, + "lifecycle_state": "created", + "log_sources": [ + { + "created_at": "2019-08-24T14:15:22Z", + "display_name": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" + } + ], + "logs_length": 0, + "logs_overflowed": true, + "name": "string", + "operating_system": "string", + "ready_at": "2019-08-24T14:15:22Z", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", + "scripts": [ + { + "cron": "string", + "log_path": "string", + "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", + "run_on_start": true, + "run_on_stop": true, + "script": "string", + "start_blocks_login": true, + "timeout": 0 + } + ], + "started_at": "2019-08-24T14:15:22Z", + "startup_script_behavior": "blocking", + "status": "connecting", + "subsystems": ["envbox"], + "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_avatar_url": "string", + "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7", + "workspace_owner_name": "string" } ``` @@ -1005,154 +1005,154 @@ curl -X GET http://coder-server:8080/api/v2/workspaces/{workspace}/builds \ ```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", - "error_code": "REQUIRED_TEMPLATE_VARIABLES", - "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "queue_position": 0, - "queue_size": 0, - "started_at": "2019-08-24T14:15:22Z", - "status": "pending", - "tags": { - "property1": "string", - "property2": "string" - }, - "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" - }, - "max_deadline": "2019-08-24T14:15:22Z", - "reason": "initiator", - "resources": [ - { - "agents": [ - { - "api_version": "string", - "apps": [ - { - "command": "string", - "display_name": "string", - "external": true, - "health": "disabled", - "healthcheck": { - "interval": 0, - "threshold": 0, - "url": "string" - }, - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "sharing_level": "owner", - "slug": "string", - "subdomain": true, - "subdomain_name": "string", - "url": "string" - } - ], - "architecture": "string", - "connection_timeout_seconds": 0, - "created_at": "2019-08-24T14:15:22Z", - "directory": "string", - "disconnected_at": "2019-08-24T14:15:22Z", - "display_apps": ["vscode"], - "environment_variables": { - "property1": "string", - "property2": "string" - }, - "expanded_directory": "string", - "first_connected_at": "2019-08-24T14:15:22Z", - "health": { - "healthy": false, - "reason": "agent has lost connection" - }, - "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 - } - }, - "lifecycle_state": "created", - "log_sources": [ - { - "created_at": "2019-08-24T14:15:22Z", - "display_name": "string", - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" - } - ], - "logs_length": 0, - "logs_overflowed": true, - "name": "string", - "operating_system": "string", - "ready_at": "2019-08-24T14:15:22Z", - "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", - "scripts": [ - { - "cron": "string", - "log_path": "string", - "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", - "run_on_start": true, - "run_on_stop": true, - "script": "string", - "start_blocks_login": true, - "timeout": 0 - } - ], - "started_at": "2019-08-24T14:15:22Z", - "startup_script_behavior": "blocking", - "status": "connecting", - "subsystems": ["envbox"], - "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_avatar_url": "string", - "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7", - "workspace_owner_name": "string" - } + { + "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", + "error_code": "REQUIRED_TEMPLATE_VARIABLES", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "queue_position": 0, + "queue_size": 0, + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" + }, + "max_deadline": "2019-08-24T14:15:22Z", + "reason": "initiator", + "resources": [ + { + "agents": [ + { + "api_version": "string", + "apps": [ + { + "command": "string", + "display_name": "string", + "external": true, + "health": "disabled", + "healthcheck": { + "interval": 0, + "threshold": 0, + "url": "string" + }, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "sharing_level": "owner", + "slug": "string", + "subdomain": true, + "subdomain_name": "string", + "url": "string" + } + ], + "architecture": "string", + "connection_timeout_seconds": 0, + "created_at": "2019-08-24T14:15:22Z", + "directory": "string", + "disconnected_at": "2019-08-24T14:15:22Z", + "display_apps": ["vscode"], + "environment_variables": { + "property1": "string", + "property2": "string" + }, + "expanded_directory": "string", + "first_connected_at": "2019-08-24T14:15:22Z", + "health": { + "healthy": false, + "reason": "agent has lost connection" + }, + "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 + } + }, + "lifecycle_state": "created", + "log_sources": [ + { + "created_at": "2019-08-24T14:15:22Z", + "display_name": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" + } + ], + "logs_length": 0, + "logs_overflowed": true, + "name": "string", + "operating_system": "string", + "ready_at": "2019-08-24T14:15:22Z", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", + "scripts": [ + { + "cron": "string", + "log_path": "string", + "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", + "run_on_start": true, + "run_on_stop": true, + "script": "string", + "start_blocks_login": true, + "timeout": 0 + } + ], + "started_at": "2019-08-24T14:15:22Z", + "startup_script_behavior": "blocking", + "status": "connecting", + "subsystems": ["envbox"], + "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_avatar_url": "string", + "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7", + "workspace_owner_name": "string" + } ] ``` @@ -1358,18 +1358,18 @@ curl -X POST http://coder-server:8080/api/v2/workspaces/{workspace}/builds \ ```json { - "dry_run": true, - "log_level": "debug", - "orphan": true, - "rich_parameter_values": [ - { - "name": "string", - "value": "string" - } - ], - "state": [0], - "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1", - "transition": "create" + "dry_run": true, + "log_level": "debug", + "orphan": true, + "rich_parameter_values": [ + { + "name": "string", + "value": "string" + } + ], + "state": [0], + "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1", + "transition": "create" } ``` @@ -1386,152 +1386,152 @@ curl -X POST http://coder-server:8080/api/v2/workspaces/{workspace}/builds \ ```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", - "error_code": "REQUIRED_TEMPLATE_VARIABLES", - "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "queue_position": 0, - "queue_size": 0, - "started_at": "2019-08-24T14:15:22Z", - "status": "pending", - "tags": { - "property1": "string", - "property2": "string" - }, - "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" - }, - "max_deadline": "2019-08-24T14:15:22Z", - "reason": "initiator", - "resources": [ - { - "agents": [ - { - "api_version": "string", - "apps": [ - { - "command": "string", - "display_name": "string", - "external": true, - "health": "disabled", - "healthcheck": { - "interval": 0, - "threshold": 0, - "url": "string" - }, - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "sharing_level": "owner", - "slug": "string", - "subdomain": true, - "subdomain_name": "string", - "url": "string" - } - ], - "architecture": "string", - "connection_timeout_seconds": 0, - "created_at": "2019-08-24T14:15:22Z", - "directory": "string", - "disconnected_at": "2019-08-24T14:15:22Z", - "display_apps": ["vscode"], - "environment_variables": { - "property1": "string", - "property2": "string" - }, - "expanded_directory": "string", - "first_connected_at": "2019-08-24T14:15:22Z", - "health": { - "healthy": false, - "reason": "agent has lost connection" - }, - "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 - } - }, - "lifecycle_state": "created", - "log_sources": [ - { - "created_at": "2019-08-24T14:15:22Z", - "display_name": "string", - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" - } - ], - "logs_length": 0, - "logs_overflowed": true, - "name": "string", - "operating_system": "string", - "ready_at": "2019-08-24T14:15:22Z", - "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", - "scripts": [ - { - "cron": "string", - "log_path": "string", - "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", - "run_on_start": true, - "run_on_stop": true, - "script": "string", - "start_blocks_login": true, - "timeout": 0 - } - ], - "started_at": "2019-08-24T14:15:22Z", - "startup_script_behavior": "blocking", - "status": "connecting", - "subsystems": ["envbox"], - "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_avatar_url": "string", - "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7", - "workspace_owner_name": "string" + "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", + "error_code": "REQUIRED_TEMPLATE_VARIABLES", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "queue_position": 0, + "queue_size": 0, + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" + }, + "max_deadline": "2019-08-24T14:15:22Z", + "reason": "initiator", + "resources": [ + { + "agents": [ + { + "api_version": "string", + "apps": [ + { + "command": "string", + "display_name": "string", + "external": true, + "health": "disabled", + "healthcheck": { + "interval": 0, + "threshold": 0, + "url": "string" + }, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "sharing_level": "owner", + "slug": "string", + "subdomain": true, + "subdomain_name": "string", + "url": "string" + } + ], + "architecture": "string", + "connection_timeout_seconds": 0, + "created_at": "2019-08-24T14:15:22Z", + "directory": "string", + "disconnected_at": "2019-08-24T14:15:22Z", + "display_apps": ["vscode"], + "environment_variables": { + "property1": "string", + "property2": "string" + }, + "expanded_directory": "string", + "first_connected_at": "2019-08-24T14:15:22Z", + "health": { + "healthy": false, + "reason": "agent has lost connection" + }, + "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 + } + }, + "lifecycle_state": "created", + "log_sources": [ + { + "created_at": "2019-08-24T14:15:22Z", + "display_name": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" + } + ], + "logs_length": 0, + "logs_overflowed": true, + "name": "string", + "operating_system": "string", + "ready_at": "2019-08-24T14:15:22Z", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", + "scripts": [ + { + "cron": "string", + "log_path": "string", + "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", + "run_on_start": true, + "run_on_stop": true, + "script": "string", + "start_blocks_login": true, + "timeout": 0 + } + ], + "started_at": "2019-08-24T14:15:22Z", + "startup_script_behavior": "blocking", + "status": "connecting", + "subsystems": ["envbox"], + "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_avatar_url": "string", + "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7", + "workspace_owner_name": "string" } ``` diff --git a/docs/reference/api/debug.md b/docs/reference/api/debug.md index 26c802c239..9ca6379316 100644 --- a/docs/reference/api/debug.md +++ b/docs/reference/api/debug.md @@ -45,332 +45,332 @@ curl -X GET http://coder-server:8080/api/v2/debug/health \ ```json { - "access_url": { - "access_url": "string", - "dismissed": true, - "error": "string", - "healthy": true, - "healthz_response": "string", - "reachable": true, - "severity": "ok", - "status_code": 0, - "warnings": [ - { - "code": "EUNKNOWN", - "message": "string" - } - ] - }, - "coder_version": "string", - "database": { - "dismissed": true, - "error": "string", - "healthy": true, - "latency": "string", - "latency_ms": 0, - "reachable": true, - "severity": "ok", - "threshold_ms": 0, - "warnings": [ - { - "code": "EUNKNOWN", - "message": "string" - } - ] - }, - "derp": { - "dismissed": true, - "error": "string", - "healthy": true, - "netcheck": { - "captivePortal": "string", - "globalV4": "string", - "globalV6": "string", - "hairPinning": "string", - "icmpv4": true, - "ipv4": true, - "ipv4CanSend": true, - "ipv6": true, - "ipv6CanSend": true, - "mappingVariesByDestIP": "string", - "oshasIPv6": true, - "pcp": "string", - "pmp": "string", - "preferredDERP": 0, - "regionLatency": { - "property1": 0, - "property2": 0 - }, - "regionV4Latency": { - "property1": 0, - "property2": 0 - }, - "regionV6Latency": { - "property1": 0, - "property2": 0 - }, - "udp": true, - "upnP": "string" - }, - "netcheck_err": "string", - "netcheck_logs": ["string"], - "regions": { - "property1": { - "error": "string", - "healthy": true, - "node_reports": [ - { - "can_exchange_messages": true, - "client_errs": [["string"]], - "client_logs": [["string"]], - "error": "string", - "healthy": true, - "node": { - "canPort80": true, - "certName": "string", - "derpport": 0, - "forceHTTP": true, - "hostName": "string", - "insecureForTests": true, - "ipv4": "string", - "ipv6": "string", - "name": "string", - "regionID": 0, - "stunonly": true, - "stunport": 0, - "stuntestIP": "string" - }, - "node_info": { - "tokenBucketBytesBurst": 0, - "tokenBucketBytesPerSecond": 0 - }, - "round_trip_ping": "string", - "round_trip_ping_ms": 0, - "severity": "ok", - "stun": { - "canSTUN": true, - "enabled": true, - "error": "string" - }, - "uses_websocket": true, - "warnings": [ - { - "code": "EUNKNOWN", - "message": "string" - } - ] - } - ], - "region": { - "avoid": true, - "embeddedRelay": true, - "nodes": [ - { - "canPort80": true, - "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" - }, - "severity": "ok", - "warnings": [ - { - "code": "EUNKNOWN", - "message": "string" - } - ] - }, - "property2": { - "error": "string", - "healthy": true, - "node_reports": [ - { - "can_exchange_messages": true, - "client_errs": [["string"]], - "client_logs": [["string"]], - "error": "string", - "healthy": true, - "node": { - "canPort80": true, - "certName": "string", - "derpport": 0, - "forceHTTP": true, - "hostName": "string", - "insecureForTests": true, - "ipv4": "string", - "ipv6": "string", - "name": "string", - "regionID": 0, - "stunonly": true, - "stunport": 0, - "stuntestIP": "string" - }, - "node_info": { - "tokenBucketBytesBurst": 0, - "tokenBucketBytesPerSecond": 0 - }, - "round_trip_ping": "string", - "round_trip_ping_ms": 0, - "severity": "ok", - "stun": { - "canSTUN": true, - "enabled": true, - "error": "string" - }, - "uses_websocket": true, - "warnings": [ - { - "code": "EUNKNOWN", - "message": "string" - } - ] - } - ], - "region": { - "avoid": true, - "embeddedRelay": true, - "nodes": [ - { - "canPort80": true, - "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" - }, - "severity": "ok", - "warnings": [ - { - "code": "EUNKNOWN", - "message": "string" - } - ] - } - }, - "severity": "ok", - "warnings": [ - { - "code": "EUNKNOWN", - "message": "string" - } - ] - }, - "healthy": true, - "provisioner_daemons": { - "dismissed": true, - "error": "string", - "items": [ - { - "provisioner_daemon": { - "api_version": "string", - "created_at": "2019-08-24T14:15:22Z", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "last_seen_at": "2019-08-24T14:15:22Z", - "name": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "provisioners": ["string"], - "tags": { - "property1": "string", - "property2": "string" - }, - "version": "string" - }, - "warnings": [ - { - "code": "EUNKNOWN", - "message": "string" - } - ] - } - ], - "severity": "ok", - "warnings": [ - { - "code": "EUNKNOWN", - "message": "string" - } - ] - }, - "severity": "ok", - "time": "2019-08-24T14:15:22Z", - "websocket": { - "body": "string", - "code": 0, - "dismissed": true, - "error": "string", - "healthy": true, - "severity": "ok", - "warnings": [ - { - "code": "EUNKNOWN", - "message": "string" - } - ] - }, - "workspace_proxy": { - "dismissed": true, - "error": "string", - "healthy": true, - "severity": "ok", - "warnings": [ - { - "code": "EUNKNOWN", - "message": "string" - } - ], - "workspace_proxies": { - "regions": [ - { - "created_at": "2019-08-24T14:15:22Z", - "deleted": true, - "derp_enabled": true, - "derp_only": true, - "display_name": "string", - "healthy": true, - "icon_url": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "name": "string", - "path_app_url": "string", - "status": { - "checked_at": "2019-08-24T14:15:22Z", - "report": { - "errors": ["string"], - "warnings": ["string"] - }, - "status": "ok" - }, - "updated_at": "2019-08-24T14:15:22Z", - "version": "string", - "wildcard_hostname": "string" - } - ] - } - } + "access_url": { + "access_url": "string", + "dismissed": true, + "error": "string", + "healthy": true, + "healthz_response": "string", + "reachable": true, + "severity": "ok", + "status_code": 0, + "warnings": [ + { + "code": "EUNKNOWN", + "message": "string" + } + ] + }, + "coder_version": "string", + "database": { + "dismissed": true, + "error": "string", + "healthy": true, + "latency": "string", + "latency_ms": 0, + "reachable": true, + "severity": "ok", + "threshold_ms": 0, + "warnings": [ + { + "code": "EUNKNOWN", + "message": "string" + } + ] + }, + "derp": { + "dismissed": true, + "error": "string", + "healthy": true, + "netcheck": { + "captivePortal": "string", + "globalV4": "string", + "globalV6": "string", + "hairPinning": "string", + "icmpv4": true, + "ipv4": true, + "ipv4CanSend": true, + "ipv6": true, + "ipv6CanSend": true, + "mappingVariesByDestIP": "string", + "oshasIPv6": true, + "pcp": "string", + "pmp": "string", + "preferredDERP": 0, + "regionLatency": { + "property1": 0, + "property2": 0 + }, + "regionV4Latency": { + "property1": 0, + "property2": 0 + }, + "regionV6Latency": { + "property1": 0, + "property2": 0 + }, + "udp": true, + "upnP": "string" + }, + "netcheck_err": "string", + "netcheck_logs": ["string"], + "regions": { + "property1": { + "error": "string", + "healthy": true, + "node_reports": [ + { + "can_exchange_messages": true, + "client_errs": [["string"]], + "client_logs": [["string"]], + "error": "string", + "healthy": true, + "node": { + "canPort80": true, + "certName": "string", + "derpport": 0, + "forceHTTP": true, + "hostName": "string", + "insecureForTests": true, + "ipv4": "string", + "ipv6": "string", + "name": "string", + "regionID": 0, + "stunonly": true, + "stunport": 0, + "stuntestIP": "string" + }, + "node_info": { + "tokenBucketBytesBurst": 0, + "tokenBucketBytesPerSecond": 0 + }, + "round_trip_ping": "string", + "round_trip_ping_ms": 0, + "severity": "ok", + "stun": { + "canSTUN": true, + "enabled": true, + "error": "string" + }, + "uses_websocket": true, + "warnings": [ + { + "code": "EUNKNOWN", + "message": "string" + } + ] + } + ], + "region": { + "avoid": true, + "embeddedRelay": true, + "nodes": [ + { + "canPort80": true, + "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" + }, + "severity": "ok", + "warnings": [ + { + "code": "EUNKNOWN", + "message": "string" + } + ] + }, + "property2": { + "error": "string", + "healthy": true, + "node_reports": [ + { + "can_exchange_messages": true, + "client_errs": [["string"]], + "client_logs": [["string"]], + "error": "string", + "healthy": true, + "node": { + "canPort80": true, + "certName": "string", + "derpport": 0, + "forceHTTP": true, + "hostName": "string", + "insecureForTests": true, + "ipv4": "string", + "ipv6": "string", + "name": "string", + "regionID": 0, + "stunonly": true, + "stunport": 0, + "stuntestIP": "string" + }, + "node_info": { + "tokenBucketBytesBurst": 0, + "tokenBucketBytesPerSecond": 0 + }, + "round_trip_ping": "string", + "round_trip_ping_ms": 0, + "severity": "ok", + "stun": { + "canSTUN": true, + "enabled": true, + "error": "string" + }, + "uses_websocket": true, + "warnings": [ + { + "code": "EUNKNOWN", + "message": "string" + } + ] + } + ], + "region": { + "avoid": true, + "embeddedRelay": true, + "nodes": [ + { + "canPort80": true, + "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" + }, + "severity": "ok", + "warnings": [ + { + "code": "EUNKNOWN", + "message": "string" + } + ] + } + }, + "severity": "ok", + "warnings": [ + { + "code": "EUNKNOWN", + "message": "string" + } + ] + }, + "healthy": true, + "provisioner_daemons": { + "dismissed": true, + "error": "string", + "items": [ + { + "provisioner_daemon": { + "api_version": "string", + "created_at": "2019-08-24T14:15:22Z", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "last_seen_at": "2019-08-24T14:15:22Z", + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "provisioners": ["string"], + "tags": { + "property1": "string", + "property2": "string" + }, + "version": "string" + }, + "warnings": [ + { + "code": "EUNKNOWN", + "message": "string" + } + ] + } + ], + "severity": "ok", + "warnings": [ + { + "code": "EUNKNOWN", + "message": "string" + } + ] + }, + "severity": "ok", + "time": "2019-08-24T14:15:22Z", + "websocket": { + "body": "string", + "code": 0, + "dismissed": true, + "error": "string", + "healthy": true, + "severity": "ok", + "warnings": [ + { + "code": "EUNKNOWN", + "message": "string" + } + ] + }, + "workspace_proxy": { + "dismissed": true, + "error": "string", + "healthy": true, + "severity": "ok", + "warnings": [ + { + "code": "EUNKNOWN", + "message": "string" + } + ], + "workspace_proxies": { + "regions": [ + { + "created_at": "2019-08-24T14:15:22Z", + "deleted": true, + "derp_enabled": true, + "derp_only": true, + "display_name": "string", + "healthy": true, + "icon_url": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "string", + "path_app_url": "string", + "status": { + "checked_at": "2019-08-24T14:15:22Z", + "report": { + "errors": ["string"], + "warnings": ["string"] + }, + "status": "ok" + }, + "updated_at": "2019-08-24T14:15:22Z", + "version": "string", + "wildcard_hostname": "string" + } + ] + } + } } ``` @@ -401,7 +401,7 @@ curl -X GET http://coder-server:8080/api/v2/debug/health/settings \ ```json { - "dismissed_healthchecks": ["DERP"] + "dismissed_healthchecks": ["DERP"] } ``` @@ -431,7 +431,7 @@ curl -X PUT http://coder-server:8080/api/v2/debug/health/settings \ ```json { - "dismissed_healthchecks": ["DERP"] + "dismissed_healthchecks": ["DERP"] } ``` @@ -447,7 +447,7 @@ curl -X PUT http://coder-server:8080/api/v2/debug/health/settings \ ```json { - "dismissed_healthchecks": ["DERP"] + "dismissed_healthchecks": ["DERP"] } ``` diff --git a/docs/reference/api/enterprise.md b/docs/reference/api/enterprise.md index 5b220f1d70..d1df96eee1 100644 --- a/docs/reference/api/enterprise.md +++ b/docs/reference/api/enterprise.md @@ -19,27 +19,27 @@ curl -X GET http://coder-server:8080/api/v2/appearance \ ```json { - "announcement_banners": [ - { - "background_color": "string", - "enabled": true, - "message": "string" - } - ], - "application_name": "string", - "logo_url": "string", - "service_banner": { - "background_color": "string", - "enabled": true, - "message": "string" - }, - "support_links": [ - { - "icon": "bug", - "name": "string", - "target": "string" - } - ] + "announcement_banners": [ + { + "background_color": "string", + "enabled": true, + "message": "string" + } + ], + "application_name": "string", + "logo_url": "string", + "service_banner": { + "background_color": "string", + "enabled": true, + "message": "string" + }, + "support_links": [ + { + "icon": "bug", + "name": "string", + "target": "string" + } + ] } ``` @@ -69,20 +69,20 @@ curl -X PUT http://coder-server:8080/api/v2/appearance \ ```json { - "announcement_banners": [ - { - "background_color": "string", - "enabled": true, - "message": "string" - } - ], - "application_name": "string", - "logo_url": "string", - "service_banner": { - "background_color": "string", - "enabled": true, - "message": "string" - } + "announcement_banners": [ + { + "background_color": "string", + "enabled": true, + "message": "string" + } + ], + "application_name": "string", + "logo_url": "string", + "service_banner": { + "background_color": "string", + "enabled": true, + "message": "string" + } } ``` @@ -98,20 +98,20 @@ curl -X PUT http://coder-server:8080/api/v2/appearance \ ```json { - "announcement_banners": [ - { - "background_color": "string", - "enabled": true, - "message": "string" - } - ], - "application_name": "string", - "logo_url": "string", - "service_banner": { - "background_color": "string", - "enabled": true, - "message": "string" - } + "announcement_banners": [ + { + "background_color": "string", + "enabled": true, + "message": "string" + } + ], + "application_name": "string", + "logo_url": "string", + "service_banner": { + "background_color": "string", + "enabled": true, + "message": "string" + } } ``` @@ -142,26 +142,26 @@ curl -X GET http://coder-server:8080/api/v2/entitlements \ ```json { - "errors": ["string"], - "features": { - "property1": { - "actual": 0, - "enabled": true, - "entitlement": "entitled", - "limit": 0 - }, - "property2": { - "actual": 0, - "enabled": true, - "entitlement": "entitled", - "limit": 0 - } - }, - "has_license": true, - "refreshed_at": "2019-08-24T14:15:22Z", - "require_telemetry": true, - "trial": true, - "warnings": ["string"] + "errors": ["string"], + "features": { + "property1": { + "actual": 0, + "enabled": true, + "entitlement": "entitled", + "limit": 0 + }, + "property2": { + "actual": 0, + "enabled": true, + "entitlement": "entitled", + "limit": 0 + } + }, + "has_license": true, + "refreshed_at": "2019-08-24T14:15:22Z", + "require_telemetry": true, + "trial": true, + "warnings": ["string"] } ``` @@ -199,31 +199,31 @@ curl -X GET http://coder-server:8080/api/v2/groups?organization=string&has_membe ```json [ - { - "avatar_url": "string", - "display_name": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "members": [ - { - "avatar_url": "http://example.com", - "created_at": "2019-08-24T14:15:22Z", - "email": "user@example.com", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "last_seen_at": "2019-08-24T14:15:22Z", - "login_type": "", - "name": "string", - "status": "active", - "theme_preference": "string", - "updated_at": "2019-08-24T14:15:22Z", - "username": "string" - } - ], - "name": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "quota_allowance": 0, - "source": "user", - "total_member_count": 0 - } + { + "avatar_url": "string", + "display_name": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "members": [ + { + "avatar_url": "http://example.com", + "created_at": "2019-08-24T14:15:22Z", + "email": "user@example.com", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "last_seen_at": "2019-08-24T14:15:22Z", + "login_type": "", + "name": "string", + "status": "active", + "theme_preference": "string", + "updated_at": "2019-08-24T14:15:22Z", + "username": "string" + } + ], + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "quota_allowance": 0, + "source": "user", + "total_member_count": 0 + } ] ``` @@ -303,29 +303,29 @@ curl -X GET http://coder-server:8080/api/v2/groups/{group} \ ```json { - "avatar_url": "string", - "display_name": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "members": [ - { - "avatar_url": "http://example.com", - "created_at": "2019-08-24T14:15:22Z", - "email": "user@example.com", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "last_seen_at": "2019-08-24T14:15:22Z", - "login_type": "", - "name": "string", - "status": "active", - "theme_preference": "string", - "updated_at": "2019-08-24T14:15:22Z", - "username": "string" - } - ], - "name": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "quota_allowance": 0, - "source": "user", - "total_member_count": 0 + "avatar_url": "string", + "display_name": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "members": [ + { + "avatar_url": "http://example.com", + "created_at": "2019-08-24T14:15:22Z", + "email": "user@example.com", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "last_seen_at": "2019-08-24T14:15:22Z", + "login_type": "", + "name": "string", + "status": "active", + "theme_preference": "string", + "updated_at": "2019-08-24T14:15:22Z", + "username": "string" + } + ], + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "quota_allowance": 0, + "source": "user", + "total_member_count": 0 } ``` @@ -362,29 +362,29 @@ curl -X DELETE http://coder-server:8080/api/v2/groups/{group} \ ```json { - "avatar_url": "string", - "display_name": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "members": [ - { - "avatar_url": "http://example.com", - "created_at": "2019-08-24T14:15:22Z", - "email": "user@example.com", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "last_seen_at": "2019-08-24T14:15:22Z", - "login_type": "", - "name": "string", - "status": "active", - "theme_preference": "string", - "updated_at": "2019-08-24T14:15:22Z", - "username": "string" - } - ], - "name": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "quota_allowance": 0, - "source": "user", - "total_member_count": 0 + "avatar_url": "string", + "display_name": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "members": [ + { + "avatar_url": "http://example.com", + "created_at": "2019-08-24T14:15:22Z", + "email": "user@example.com", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "last_seen_at": "2019-08-24T14:15:22Z", + "login_type": "", + "name": "string", + "status": "active", + "theme_preference": "string", + "updated_at": "2019-08-24T14:15:22Z", + "username": "string" + } + ], + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "quota_allowance": 0, + "source": "user", + "total_member_count": 0 } ``` @@ -414,12 +414,12 @@ curl -X PATCH http://coder-server:8080/api/v2/groups/{group} \ ```json { - "add_users": ["string"], - "avatar_url": "string", - "display_name": "string", - "name": "string", - "quota_allowance": 0, - "remove_users": ["string"] + "add_users": ["string"], + "avatar_url": "string", + "display_name": "string", + "name": "string", + "quota_allowance": 0, + "remove_users": ["string"] } ``` @@ -436,29 +436,29 @@ curl -X PATCH http://coder-server:8080/api/v2/groups/{group} \ ```json { - "avatar_url": "string", - "display_name": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "members": [ - { - "avatar_url": "http://example.com", - "created_at": "2019-08-24T14:15:22Z", - "email": "user@example.com", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "last_seen_at": "2019-08-24T14:15:22Z", - "login_type": "", - "name": "string", - "status": "active", - "theme_preference": "string", - "updated_at": "2019-08-24T14:15:22Z", - "username": "string" - } - ], - "name": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "quota_allowance": 0, - "source": "user", - "total_member_count": 0 + "avatar_url": "string", + "display_name": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "members": [ + { + "avatar_url": "http://example.com", + "created_at": "2019-08-24T14:15:22Z", + "email": "user@example.com", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "last_seen_at": "2019-08-24T14:15:22Z", + "login_type": "", + "name": "string", + "status": "active", + "theme_preference": "string", + "updated_at": "2019-08-24T14:15:22Z", + "username": "string" + } + ], + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "quota_allowance": 0, + "source": "user", + "total_member_count": 0 } ``` @@ -496,12 +496,12 @@ curl -X GET http://coder-server:8080/api/v2/integrations/jfrog/xray-scan?workspa ```json { - "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978", - "critical": 0, - "high": 0, - "medium": 0, - "results_url": "string", - "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9" + "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978", + "critical": 0, + "high": 0, + "medium": 0, + "results_url": "string", + "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9" } ``` @@ -531,12 +531,12 @@ curl -X POST http://coder-server:8080/api/v2/integrations/jfrog/xray-scan \ ```json { - "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978", - "critical": 0, - "high": 0, - "medium": 0, - "results_url": "string", - "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9" + "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978", + "critical": 0, + "high": 0, + "medium": 0, + "results_url": "string", + "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9" } ``` @@ -552,14 +552,14 @@ curl -X POST http://coder-server:8080/api/v2/integrations/jfrog/xray-scan \ ```json { - "detail": "string", - "message": "string", - "validations": [ - { - "detail": "string", - "field": "string" - } - ] + "detail": "string", + "message": "string", + "validations": [ + { + "detail": "string", + "field": "string" + } + ] } ``` @@ -590,12 +590,12 @@ curl -X GET http://coder-server:8080/api/v2/licenses \ ```json [ - { - "claims": {}, - "id": 0, - "uploaded_at": "2019-08-24T14:15:22Z", - "uuid": "095be615-a8ad-4c33-8e9c-c7612fbf6c9f" - } + { + "claims": {}, + "id": 0, + "uploaded_at": "2019-08-24T14:15:22Z", + "uuid": "095be615-a8ad-4c33-8e9c-c7612fbf6c9f" + } ] ``` @@ -697,17 +697,17 @@ curl -X GET http://coder-server:8080/api/v2/oauth2-provider/apps \ ```json [ - { - "callback_url": "string", - "endpoints": { - "authorization": "string", - "device_authorization": "string", - "token": "string" - }, - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "name": "string" - } + { + "callback_url": "string", + "endpoints": { + "authorization": "string", + "device_authorization": "string", + "token": "string" + }, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "string" + } ] ``` @@ -753,9 +753,9 @@ curl -X POST http://coder-server:8080/api/v2/oauth2-provider/apps \ ```json { - "callback_url": "string", - "icon": "string", - "name": "string" + "callback_url": "string", + "icon": "string", + "name": "string" } ``` @@ -771,15 +771,15 @@ curl -X POST http://coder-server:8080/api/v2/oauth2-provider/apps \ ```json { - "callback_url": "string", - "endpoints": { - "authorization": "string", - "device_authorization": "string", - "token": "string" - }, - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "name": "string" + "callback_url": "string", + "endpoints": { + "authorization": "string", + "device_authorization": "string", + "token": "string" + }, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "string" } ``` @@ -816,15 +816,15 @@ curl -X GET http://coder-server:8080/api/v2/oauth2-provider/apps/{app} \ ```json { - "callback_url": "string", - "endpoints": { - "authorization": "string", - "device_authorization": "string", - "token": "string" - }, - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "name": "string" + "callback_url": "string", + "endpoints": { + "authorization": "string", + "device_authorization": "string", + "token": "string" + }, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "string" } ``` @@ -854,9 +854,9 @@ curl -X PUT http://coder-server:8080/api/v2/oauth2-provider/apps/{app} \ ```json { - "callback_url": "string", - "icon": "string", - "name": "string" + "callback_url": "string", + "icon": "string", + "name": "string" } ``` @@ -873,15 +873,15 @@ curl -X PUT http://coder-server:8080/api/v2/oauth2-provider/apps/{app} \ ```json { - "callback_url": "string", - "endpoints": { - "authorization": "string", - "device_authorization": "string", - "token": "string" - }, - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "name": "string" + "callback_url": "string", + "endpoints": { + "authorization": "string", + "device_authorization": "string", + "token": "string" + }, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "string" } ``` @@ -944,11 +944,11 @@ curl -X GET http://coder-server:8080/api/v2/oauth2-provider/apps/{app}/secrets \ ```json [ - { - "client_secret_truncated": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "last_used_at": "string" - } + { + "client_secret_truncated": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "last_used_at": "string" + } ] ``` @@ -996,10 +996,10 @@ curl -X POST http://coder-server:8080/api/v2/oauth2-provider/apps/{app}/secrets ```json [ - { - "client_secret_full": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08" - } + { + "client_secret_full": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08" + } ] ``` @@ -1130,10 +1130,10 @@ grant_type: authorization_code ```json { - "access_token": "string", - "expiry": "string", - "refresh_token": "string", - "token_type": "string" + "access_token": "string", + "expiry": "string", + "refresh_token": "string", + "token_type": "string" } ``` @@ -1194,31 +1194,31 @@ curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/groups ```json [ - { - "avatar_url": "string", - "display_name": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "members": [ - { - "avatar_url": "http://example.com", - "created_at": "2019-08-24T14:15:22Z", - "email": "user@example.com", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "last_seen_at": "2019-08-24T14:15:22Z", - "login_type": "", - "name": "string", - "status": "active", - "theme_preference": "string", - "updated_at": "2019-08-24T14:15:22Z", - "username": "string" - } - ], - "name": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "quota_allowance": 0, - "source": "user", - "total_member_count": 0 - } + { + "avatar_url": "string", + "display_name": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "members": [ + { + "avatar_url": "http://example.com", + "created_at": "2019-08-24T14:15:22Z", + "email": "user@example.com", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "last_seen_at": "2019-08-24T14:15:22Z", + "login_type": "", + "name": "string", + "status": "active", + "theme_preference": "string", + "updated_at": "2019-08-24T14:15:22Z", + "username": "string" + } + ], + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "quota_allowance": 0, + "source": "user", + "total_member_count": 0 + } ] ``` @@ -1291,10 +1291,10 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/groups ```json { - "avatar_url": "string", - "display_name": "string", - "name": "string", - "quota_allowance": 0 + "avatar_url": "string", + "display_name": "string", + "name": "string", + "quota_allowance": 0 } ``` @@ -1311,29 +1311,29 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/groups ```json { - "avatar_url": "string", - "display_name": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "members": [ - { - "avatar_url": "http://example.com", - "created_at": "2019-08-24T14:15:22Z", - "email": "user@example.com", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "last_seen_at": "2019-08-24T14:15:22Z", - "login_type": "", - "name": "string", - "status": "active", - "theme_preference": "string", - "updated_at": "2019-08-24T14:15:22Z", - "username": "string" - } - ], - "name": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "quota_allowance": 0, - "source": "user", - "total_member_count": 0 + "avatar_url": "string", + "display_name": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "members": [ + { + "avatar_url": "http://example.com", + "created_at": "2019-08-24T14:15:22Z", + "email": "user@example.com", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "last_seen_at": "2019-08-24T14:15:22Z", + "login_type": "", + "name": "string", + "status": "active", + "theme_preference": "string", + "updated_at": "2019-08-24T14:15:22Z", + "username": "string" + } + ], + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "quota_allowance": 0, + "source": "user", + "total_member_count": 0 } ``` @@ -1371,29 +1371,29 @@ curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/groups/ ```json { - "avatar_url": "string", - "display_name": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "members": [ - { - "avatar_url": "http://example.com", - "created_at": "2019-08-24T14:15:22Z", - "email": "user@example.com", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "last_seen_at": "2019-08-24T14:15:22Z", - "login_type": "", - "name": "string", - "status": "active", - "theme_preference": "string", - "updated_at": "2019-08-24T14:15:22Z", - "username": "string" - } - ], - "name": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "quota_allowance": 0, - "source": "user", - "total_member_count": 0 + "avatar_url": "string", + "display_name": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "members": [ + { + "avatar_url": "http://example.com", + "created_at": "2019-08-24T14:15:22Z", + "email": "user@example.com", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "last_seen_at": "2019-08-24T14:15:22Z", + "login_type": "", + "name": "string", + "status": "active", + "theme_preference": "string", + "updated_at": "2019-08-24T14:15:22Z", + "username": "string" + } + ], + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "quota_allowance": 0, + "source": "user", + "total_member_count": 0 } ``` @@ -1430,20 +1430,20 @@ curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/provisi ```json [ - { - "api_version": "string", - "created_at": "2019-08-24T14:15:22Z", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "last_seen_at": "2019-08-24T14:15:22Z", - "name": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "provisioners": ["string"], - "tags": { - "property1": "string", - "property2": "string" - }, - "version": "string" - } + { + "api_version": "string", + "created_at": "2019-08-24T14:15:22Z", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "last_seen_at": "2019-08-24T14:15:22Z", + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "provisioners": ["string"], + "tags": { + "property1": "string", + "property2": "string" + }, + "version": "string" + } ] ``` @@ -1524,16 +1524,16 @@ curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/provisi ```json [ - { - "created_at": "2019-08-24T14:15:22Z", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "name": "string", - "organization": "452c1a86-a0af-475b-b03f-724878b0f387", - "tags": { - "property1": "string", - "property2": "string" - } - } + { + "created_at": "2019-08-24T14:15:22Z", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "string", + "organization": "452c1a86-a0af-475b-b03f-724878b0f387", + "tags": { + "property1": "string", + "property2": "string" + } + } ] ``` @@ -1584,7 +1584,7 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/provis ```json { - "key": "string" + "key": "string" } ``` @@ -1642,15 +1642,15 @@ curl -X GET http://coder-server:8080/api/v2/replicas \ ```json [ - { - "created_at": "2019-08-24T14:15:22Z", - "database_latency": 0, - "error": "string", - "hostname": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "region_id": 0, - "relay_address": "string" - } + { + "created_at": "2019-08-24T14:15:22Z", + "database_latency": 0, + "error": "string", + "hostname": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "region_id": 0, + "relay_address": "string" + } ] ``` @@ -1715,26 +1715,26 @@ curl -X POST http://coder-server:8080/api/v2/scim/v2/Users \ ```json { - "active": true, - "emails": [ - { - "display": "string", - "primary": true, - "type": "string", - "value": "user@example.com" - } - ], - "groups": [null], - "id": "string", - "meta": { - "resourceType": "string" - }, - "name": { - "familyName": "string", - "givenName": "string" - }, - "schemas": ["string"], - "userName": "string" + "active": true, + "emails": [ + { + "display": "string", + "primary": true, + "type": "string", + "value": "user@example.com" + } + ], + "groups": [null], + "id": "string", + "meta": { + "resourceType": "string" + }, + "name": { + "familyName": "string", + "givenName": "string" + }, + "schemas": ["string"], + "userName": "string" } ``` @@ -1750,26 +1750,26 @@ curl -X POST http://coder-server:8080/api/v2/scim/v2/Users \ ```json { - "active": true, - "emails": [ - { - "display": "string", - "primary": true, - "type": "string", - "value": "user@example.com" - } - ], - "groups": [null], - "id": "string", - "meta": { - "resourceType": "string" - }, - "name": { - "familyName": "string", - "givenName": "string" - }, - "schemas": ["string"], - "userName": "string" + "active": true, + "emails": [ + { + "display": "string", + "primary": true, + "type": "string", + "value": "user@example.com" + } + ], + "groups": [null], + "id": "string", + "meta": { + "resourceType": "string" + }, + "name": { + "familyName": "string", + "givenName": "string" + }, + "schemas": ["string"], + "userName": "string" } ``` @@ -1825,26 +1825,26 @@ curl -X PATCH http://coder-server:8080/api/v2/scim/v2/Users/{id} \ ```json { - "active": true, - "emails": [ - { - "display": "string", - "primary": true, - "type": "string", - "value": "user@example.com" - } - ], - "groups": [null], - "id": "string", - "meta": { - "resourceType": "string" - }, - "name": { - "familyName": "string", - "givenName": "string" - }, - "schemas": ["string"], - "userName": "string" + "active": true, + "emails": [ + { + "display": "string", + "primary": true, + "type": "string", + "value": "user@example.com" + } + ], + "groups": [null], + "id": "string", + "meta": { + "resourceType": "string" + }, + "name": { + "familyName": "string", + "givenName": "string" + }, + "schemas": ["string"], + "userName": "string" } ``` @@ -1861,25 +1861,25 @@ curl -X PATCH http://coder-server:8080/api/v2/scim/v2/Users/{id} \ ```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", - "login_type": "", - "name": "string", - "organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "roles": [ - { - "display_name": "string", - "name": "string", - "organization_id": "string" - } - ], - "status": "active", - "theme_preference": "string", - "updated_at": "2019-08-24T14:15:22Z", - "username": "string" + "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", + "login_type": "", + "name": "string", + "organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "roles": [ + { + "display_name": "string", + "name": "string", + "organization_id": "string" + } + ], + "status": "active", + "theme_preference": "string", + "updated_at": "2019-08-24T14:15:22Z", + "username": "string" } ``` @@ -1916,28 +1916,28 @@ curl -X GET http://coder-server:8080/api/v2/templates/{template}/acl \ ```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", - "login_type": "", - "name": "string", - "organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "role": "admin", - "roles": [ - { - "display_name": "string", - "name": "string", - "organization_id": "string" - } - ], - "status": "active", - "theme_preference": "string", - "updated_at": "2019-08-24T14:15:22Z", - "username": "string" - } + { + "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", + "login_type": "", + "name": "string", + "organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "role": "admin", + "roles": [ + { + "display_name": "string", + "name": "string", + "organization_id": "string" + } + ], + "status": "active", + "theme_preference": "string", + "updated_at": "2019-08-24T14:15:22Z", + "username": "string" + } ] ``` @@ -2007,14 +2007,14 @@ curl -X PATCH http://coder-server:8080/api/v2/templates/{template}/acl \ ```json { - "group_perms": { - "8bd26b20-f3e8-48be-a903-46bb920cf671": "use", - ">": "admin" - }, - "user_perms": { - "4df59e74-c027-470b-ab4d-cbba8963a5e9": "use", - "": "admin" - } + "group_perms": { + "8bd26b20-f3e8-48be-a903-46bb920cf671": "use", + ">": "admin" + }, + "user_perms": { + "4df59e74-c027-470b-ab4d-cbba8963a5e9": "use", + "": "admin" + } } ``` @@ -2031,14 +2031,14 @@ curl -X PATCH http://coder-server:8080/api/v2/templates/{template}/acl \ ```json { - "detail": "string", - "message": "string", - "validations": [ - { - "detail": "string", - "field": "string" - } - ] + "detail": "string", + "message": "string", + "validations": [ + { + "detail": "string", + "field": "string" + } + ] } ``` @@ -2075,50 +2075,50 @@ curl -X GET http://coder-server:8080/api/v2/templates/{template}/acl/available \ ```json [ - { - "groups": [ - { - "avatar_url": "string", - "display_name": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "members": [ - { - "avatar_url": "http://example.com", - "created_at": "2019-08-24T14:15:22Z", - "email": "user@example.com", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "last_seen_at": "2019-08-24T14:15:22Z", - "login_type": "", - "name": "string", - "status": "active", - "theme_preference": "string", - "updated_at": "2019-08-24T14:15:22Z", - "username": "string" - } - ], - "name": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "quota_allowance": 0, - "source": "user", - "total_member_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", - "login_type": "", - "name": "string", - "status": "active", - "theme_preference": "string", - "updated_at": "2019-08-24T14:15:22Z", - "username": "string" - } - ] - } + { + "groups": [ + { + "avatar_url": "string", + "display_name": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "members": [ + { + "avatar_url": "http://example.com", + "created_at": "2019-08-24T14:15:22Z", + "email": "user@example.com", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "last_seen_at": "2019-08-24T14:15:22Z", + "login_type": "", + "name": "string", + "status": "active", + "theme_preference": "string", + "updated_at": "2019-08-24T14:15:22Z", + "username": "string" + } + ], + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "quota_allowance": 0, + "source": "user", + "total_member_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", + "login_type": "", + "name": "string", + "status": "active", + "theme_preference": "string", + "updated_at": "2019-08-24T14:15:22Z", + "username": "string" + } + ] + } ] ``` @@ -2200,14 +2200,14 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/quiet-hours \ ```json [ - { - "next": "2019-08-24T14:15:22Z", - "raw_schedule": "string", - "time": "string", - "timezone": "string", - "user_can_set": true, - "user_set": true - } + { + "next": "2019-08-24T14:15:22Z", + "raw_schedule": "string", + "time": "string", + "timezone": "string", + "user_can_set": true, + "user_set": true + } ] ``` @@ -2251,7 +2251,7 @@ curl -X PUT http://coder-server:8080/api/v2/users/{user}/quiet-hours \ ```json { - "schedule": "string" + "schedule": "string" } ``` @@ -2268,14 +2268,14 @@ curl -X PUT http://coder-server:8080/api/v2/users/{user}/quiet-hours \ ```json [ - { - "next": "2019-08-24T14:15:22Z", - "raw_schedule": "string", - "time": "string", - "timezone": "string", - "user_can_set": true, - "user_set": true - } + { + "next": "2019-08-24T14:15:22Z", + "raw_schedule": "string", + "time": "string", + "timezone": "string", + "user_can_set": true, + "user_set": true + } ] ``` @@ -2326,8 +2326,8 @@ curl -X GET http://coder-server:8080/api/v2/workspace-quota/{user} \ ```json { - "budget": 0, - "credits_consumed": 0 + "budget": 0, + "credits_consumed": 0 } ``` @@ -2358,33 +2358,33 @@ curl -X GET http://coder-server:8080/api/v2/workspaceproxies \ ```json [ - { - "regions": [ - { - "created_at": "2019-08-24T14:15:22Z", - "deleted": true, - "derp_enabled": true, - "derp_only": true, - "display_name": "string", - "healthy": true, - "icon_url": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "name": "string", - "path_app_url": "string", - "status": { - "checked_at": "2019-08-24T14:15:22Z", - "report": { - "errors": ["string"], - "warnings": ["string"] - }, - "status": "ok" - }, - "updated_at": "2019-08-24T14:15:22Z", - "version": "string", - "wildcard_hostname": "string" - } - ] - } + { + "regions": [ + { + "created_at": "2019-08-24T14:15:22Z", + "deleted": true, + "derp_enabled": true, + "derp_only": true, + "display_name": "string", + "healthy": true, + "icon_url": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "string", + "path_app_url": "string", + "status": { + "checked_at": "2019-08-24T14:15:22Z", + "report": { + "errors": ["string"], + "warnings": ["string"] + }, + "status": "ok" + }, + "updated_at": "2019-08-24T14:15:22Z", + "version": "string", + "wildcard_hostname": "string" + } + ] + } ] ``` @@ -2451,9 +2451,9 @@ curl -X POST http://coder-server:8080/api/v2/workspaceproxies \ ```json { - "display_name": "string", - "icon": "string", - "name": "string" + "display_name": "string", + "icon": "string", + "name": "string" } ``` @@ -2469,27 +2469,27 @@ curl -X POST http://coder-server:8080/api/v2/workspaceproxies \ ```json { - "created_at": "2019-08-24T14:15:22Z", - "deleted": true, - "derp_enabled": true, - "derp_only": true, - "display_name": "string", - "healthy": true, - "icon_url": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "name": "string", - "path_app_url": "string", - "status": { - "checked_at": "2019-08-24T14:15:22Z", - "report": { - "errors": ["string"], - "warnings": ["string"] - }, - "status": "ok" - }, - "updated_at": "2019-08-24T14:15:22Z", - "version": "string", - "wildcard_hostname": "string" + "created_at": "2019-08-24T14:15:22Z", + "deleted": true, + "derp_enabled": true, + "derp_only": true, + "display_name": "string", + "healthy": true, + "icon_url": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "string", + "path_app_url": "string", + "status": { + "checked_at": "2019-08-24T14:15:22Z", + "report": { + "errors": ["string"], + "warnings": ["string"] + }, + "status": "ok" + }, + "updated_at": "2019-08-24T14:15:22Z", + "version": "string", + "wildcard_hostname": "string" } ``` @@ -2526,27 +2526,27 @@ curl -X GET http://coder-server:8080/api/v2/workspaceproxies/{workspaceproxy} \ ```json { - "created_at": "2019-08-24T14:15:22Z", - "deleted": true, - "derp_enabled": true, - "derp_only": true, - "display_name": "string", - "healthy": true, - "icon_url": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "name": "string", - "path_app_url": "string", - "status": { - "checked_at": "2019-08-24T14:15:22Z", - "report": { - "errors": ["string"], - "warnings": ["string"] - }, - "status": "ok" - }, - "updated_at": "2019-08-24T14:15:22Z", - "version": "string", - "wildcard_hostname": "string" + "created_at": "2019-08-24T14:15:22Z", + "deleted": true, + "derp_enabled": true, + "derp_only": true, + "display_name": "string", + "healthy": true, + "icon_url": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "string", + "path_app_url": "string", + "status": { + "checked_at": "2019-08-24T14:15:22Z", + "report": { + "errors": ["string"], + "warnings": ["string"] + }, + "status": "ok" + }, + "updated_at": "2019-08-24T14:15:22Z", + "version": "string", + "wildcard_hostname": "string" } ``` @@ -2583,14 +2583,14 @@ curl -X DELETE http://coder-server:8080/api/v2/workspaceproxies/{workspaceproxy} ```json { - "detail": "string", - "message": "string", - "validations": [ - { - "detail": "string", - "field": "string" - } - ] + "detail": "string", + "message": "string", + "validations": [ + { + "detail": "string", + "field": "string" + } + ] } ``` @@ -2620,11 +2620,11 @@ curl -X PATCH http://coder-server:8080/api/v2/workspaceproxies/{workspaceproxy} ```json { - "display_name": "string", - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "name": "string", - "regenerate_token": true + "display_name": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "string", + "regenerate_token": true } ``` @@ -2641,27 +2641,27 @@ curl -X PATCH http://coder-server:8080/api/v2/workspaceproxies/{workspaceproxy} ```json { - "created_at": "2019-08-24T14:15:22Z", - "deleted": true, - "derp_enabled": true, - "derp_only": true, - "display_name": "string", - "healthy": true, - "icon_url": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "name": "string", - "path_app_url": "string", - "status": { - "checked_at": "2019-08-24T14:15:22Z", - "report": { - "errors": ["string"], - "warnings": ["string"] - }, - "status": "ok" - }, - "updated_at": "2019-08-24T14:15:22Z", - "version": "string", - "wildcard_hostname": "string" + "created_at": "2019-08-24T14:15:22Z", + "deleted": true, + "derp_enabled": true, + "derp_only": true, + "display_name": "string", + "healthy": true, + "icon_url": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "string", + "path_app_url": "string", + "status": { + "checked_at": "2019-08-24T14:15:22Z", + "report": { + "errors": ["string"], + "warnings": ["string"] + }, + "status": "ok" + }, + "updated_at": "2019-08-24T14:15:22Z", + "version": "string", + "wildcard_hostname": "string" } ``` diff --git a/docs/reference/api/files.md b/docs/reference/api/files.md index 379f59bf57..b0c6b6d7fd 100644 --- a/docs/reference/api/files.md +++ b/docs/reference/api/files.md @@ -34,7 +34,7 @@ file: string ```json { - "hash": "19686d84-b10d-4f90-b18e-84fd3fa038fd" + "hash": "19686d84-b10d-4f90-b18e-84fd3fa038fd" } ``` diff --git a/docs/reference/api/general.md b/docs/reference/api/general.md index 52cfd25f4c..f9e00a864c 100644 --- a/docs/reference/api/general.md +++ b/docs/reference/api/general.md @@ -18,14 +18,14 @@ curl -X GET http://coder-server:8080/api/v2/ \ ```json { - "detail": "string", - "message": "string", - "validations": [ - { - "detail": "string", - "field": "string" - } - ] + "detail": "string", + "message": "string", + "validations": [ + { + "detail": "string", + "field": "string" + } + ] } ``` @@ -53,14 +53,14 @@ curl -X GET http://coder-server:8080/api/v2/buildinfo \ ```json { - "agent_api_version": "string", - "dashboard_url": "string", - "deployment_id": "string", - "external_url": "string", - "telemetry": true, - "upgrade_message": "string", - "version": "string", - "workspace_proxy": true + "agent_api_version": "string", + "dashboard_url": "string", + "deployment_id": "string", + "external_url": "string", + "telemetry": true, + "upgrade_message": "string", + "version": "string", + "workspace_proxy": true } ``` @@ -87,7 +87,7 @@ curl -X POST http://coder-server:8080/api/v2/csp/reports \ ```json { - "csp-report": {} + "csp-report": {} } ``` @@ -124,377 +124,377 @@ curl -X GET http://coder-server:8080/api/v2/deployment/config \ ```json { - "config": { - "access_url": { - "forceQuery": true, - "fragment": "string", - "host": "string", - "omitHost": true, - "opaque": "string", - "path": "string", - "rawFragment": "string", - "rawPath": "string", - "rawQuery": "string", - "scheme": "string", - "user": {} - }, - "address": { - "host": "string", - "port": "string" - }, - "agent_fallback_troubleshooting_url": { - "forceQuery": true, - "fragment": "string", - "host": "string", - "omitHost": true, - "opaque": "string", - "path": "string", - "rawFragment": "string", - "rawPath": "string", - "rawQuery": "string", - "scheme": "string", - "user": {} - }, - "agent_stat_refresh_interval": 0, - "allow_workspace_renames": true, - "autobuild_poll_interval": 0, - "browser_only": true, - "cache_directory": "string", - "cli_upgrade_message": "string", - "config": "string", - "config_ssh": { - "deploymentName": "string", - "sshconfigOptions": ["string"] - }, - "dangerous": { - "allow_all_cors": true, - "allow_path_app_sharing": true, - "allow_path_app_site_owner_access": true - }, - "derp": { - "config": { - "block_direct": true, - "force_websockets": true, - "path": "string", - "url": "string" - }, - "server": { - "enable": true, - "region_code": "string", - "region_id": 0, - "region_name": "string", - "relay_url": { - "forceQuery": true, - "fragment": "string", - "host": "string", - "omitHost": true, - "opaque": "string", - "path": "string", - "rawFragment": "string", - "rawPath": "string", - "rawQuery": "string", - "scheme": "string", - "user": {} - }, - "stun_addresses": ["string"] - } - }, - "disable_owner_workspace_exec": true, - "disable_password_auth": true, - "disable_path_apps": true, - "docs_url": { - "forceQuery": true, - "fragment": "string", - "host": "string", - "omitHost": true, - "opaque": "string", - "path": "string", - "rawFragment": "string", - "rawPath": "string", - "rawQuery": "string", - "scheme": "string", - "user": {} - }, - "enable_terraform_debug_mode": true, - "experiments": ["string"], - "external_auth": { - "value": [ - { - "app_install_url": "string", - "app_installations_url": "string", - "auth_url": "string", - "client_id": "string", - "device_code_url": "string", - "device_flow": true, - "display_icon": "string", - "display_name": "string", - "id": "string", - "no_refresh": true, - "regex": "string", - "scopes": ["string"], - "token_url": "string", - "type": "string", - "validate_url": "string" - } - ] - }, - "external_token_encryption_keys": ["string"], - "healthcheck": { - "refresh": 0, - "threshold_database": 0 - }, - "http_address": "string", - "in_memory_database": true, - "job_hang_detector_interval": 0, - "logging": { - "human": "string", - "json": "string", - "log_filter": ["string"], - "stackdriver": "string" - }, - "metrics_cache_refresh_interval": 0, - "notifications": { - "dispatch_timeout": 0, - "email": { - "auth": { - "identity": "string", - "password": "string", - "password_file": "string", - "username": "string" - }, - "force_tls": true, - "from": "string", - "hello": "string", - "smarthost": { - "host": "string", - "port": "string" - }, - "tls": { - "ca_file": "string", - "cert_file": "string", - "insecure_skip_verify": true, - "key_file": "string", - "server_name": "string", - "start_tls": true - } - }, - "fetch_interval": 0, - "lease_count": 0, - "lease_period": 0, - "max_send_attempts": 0, - "method": "string", - "retry_interval": 0, - "sync_buffer_size": 0, - "sync_interval": 0, - "webhook": { - "endpoint": { - "forceQuery": true, - "fragment": "string", - "host": "string", - "omitHost": true, - "opaque": "string", - "path": "string", - "rawFragment": "string", - "rawPath": "string", - "rawQuery": "string", - "scheme": "string", - "user": {} - } - } - }, - "oauth2": { - "github": { - "allow_everyone": true, - "allow_signups": true, - "allowed_orgs": ["string"], - "allowed_teams": ["string"], - "client_id": "string", - "client_secret": "string", - "enterprise_base_url": "string" - } - }, - "oidc": { - "allow_signups": true, - "auth_url_params": {}, - "client_cert_file": "string", - "client_id": "string", - "client_key_file": "string", - "client_secret": "string", - "email_domain": ["string"], - "email_field": "string", - "group_allow_list": ["string"], - "group_auto_create": true, - "group_mapping": {}, - "group_regex_filter": {}, - "groups_field": "string", - "icon_url": { - "forceQuery": true, - "fragment": "string", - "host": "string", - "omitHost": true, - "opaque": "string", - "path": "string", - "rawFragment": "string", - "rawPath": "string", - "rawQuery": "string", - "scheme": "string", - "user": {} - }, - "ignore_email_verified": true, - "ignore_user_info": true, - "issuer_url": "string", - "name_field": "string", - "scopes": ["string"], - "sign_in_text": "string", - "signups_disabled_text": "string", - "skip_issuer_checks": true, - "user_role_field": "string", - "user_role_mapping": {}, - "user_roles_default": ["string"], - "username_field": "string" - }, - "pg_auth": "string", - "pg_connection_url": "string", - "pprof": { - "address": { - "host": "string", - "port": "string" - }, - "enable": true - }, - "prometheus": { - "address": { - "host": "string", - "port": "string" - }, - "aggregate_agent_stats_by": ["string"], - "collect_agent_stats": true, - "collect_db_metrics": true, - "enable": true - }, - "provisioner": { - "daemon_poll_interval": 0, - "daemon_poll_jitter": 0, - "daemon_psk": "string", - "daemon_types": ["string"], - "daemons": 0, - "force_cancel_interval": 0 - }, - "proxy_health_status_interval": 0, - "proxy_trusted_headers": ["string"], - "proxy_trusted_origins": ["string"], - "rate_limit": { - "api": 0, - "disable_all": true - }, - "redirect_to_access_url": true, - "scim_api_key": "string", - "secure_auth_cookie": true, - "session_lifetime": { - "default_duration": 0, - "disable_expiry_refresh": true, - "max_token_lifetime": 0 - }, - "ssh_keygen_algorithm": "string", - "strict_transport_security": 0, - "strict_transport_security_options": ["string"], - "support": { - "links": { - "value": [ - { - "icon": "bug", - "name": "string", - "target": "string" - } - ] - } - }, - "swagger": { - "enable": true - }, - "telemetry": { - "enable": true, - "trace": true, - "url": { - "forceQuery": true, - "fragment": "string", - "host": "string", - "omitHost": true, - "opaque": "string", - "path": "string", - "rawFragment": "string", - "rawPath": "string", - "rawQuery": "string", - "scheme": "string", - "user": {} - } - }, - "terms_of_service_url": "string", - "tls": { - "address": { - "host": "string", - "port": "string" - }, - "allow_insecure_ciphers": true, - "cert_file": ["string"], - "client_auth": "string", - "client_ca_file": "string", - "client_cert_file": "string", - "client_key_file": "string", - "enable": true, - "key_file": ["string"], - "min_version": "string", - "redirect_http": true, - "supported_ciphers": ["string"] - }, - "trace": { - "capture_logs": true, - "data_dog": true, - "enable": true, - "honeycomb_api_key": "string" - }, - "update_check": true, - "user_quiet_hours_schedule": { - "allow_user_custom": true, - "default_schedule": "string" - }, - "verbose": true, - "web_terminal_renderer": "string", - "wgtunnel_host": "string", - "wildcard_access_url": "string", - "write_config": true - }, - "options": [ - { - "annotations": { - "property1": "string", - "property2": "string" - }, - "default": "string", - "description": "string", - "env": "string", - "flag": "string", - "flag_shorthand": "string", - "group": { - "description": "string", - "name": "string", - "parent": { - "description": "string", - "name": "string", - "parent": {}, - "yaml": "string" - }, - "yaml": "string" - }, - "hidden": true, - "name": "string", - "required": true, - "use_instead": [{}], - "value": null, - "value_source": "", - "yaml": "string" - } - ] + "config": { + "access_url": { + "forceQuery": true, + "fragment": "string", + "host": "string", + "omitHost": true, + "opaque": "string", + "path": "string", + "rawFragment": "string", + "rawPath": "string", + "rawQuery": "string", + "scheme": "string", + "user": {} + }, + "address": { + "host": "string", + "port": "string" + }, + "agent_fallback_troubleshooting_url": { + "forceQuery": true, + "fragment": "string", + "host": "string", + "omitHost": true, + "opaque": "string", + "path": "string", + "rawFragment": "string", + "rawPath": "string", + "rawQuery": "string", + "scheme": "string", + "user": {} + }, + "agent_stat_refresh_interval": 0, + "allow_workspace_renames": true, + "autobuild_poll_interval": 0, + "browser_only": true, + "cache_directory": "string", + "cli_upgrade_message": "string", + "config": "string", + "config_ssh": { + "deploymentName": "string", + "sshconfigOptions": ["string"] + }, + "dangerous": { + "allow_all_cors": true, + "allow_path_app_sharing": true, + "allow_path_app_site_owner_access": true + }, + "derp": { + "config": { + "block_direct": true, + "force_websockets": true, + "path": "string", + "url": "string" + }, + "server": { + "enable": true, + "region_code": "string", + "region_id": 0, + "region_name": "string", + "relay_url": { + "forceQuery": true, + "fragment": "string", + "host": "string", + "omitHost": true, + "opaque": "string", + "path": "string", + "rawFragment": "string", + "rawPath": "string", + "rawQuery": "string", + "scheme": "string", + "user": {} + }, + "stun_addresses": ["string"] + } + }, + "disable_owner_workspace_exec": true, + "disable_password_auth": true, + "disable_path_apps": true, + "docs_url": { + "forceQuery": true, + "fragment": "string", + "host": "string", + "omitHost": true, + "opaque": "string", + "path": "string", + "rawFragment": "string", + "rawPath": "string", + "rawQuery": "string", + "scheme": "string", + "user": {} + }, + "enable_terraform_debug_mode": true, + "experiments": ["string"], + "external_auth": { + "value": [ + { + "app_install_url": "string", + "app_installations_url": "string", + "auth_url": "string", + "client_id": "string", + "device_code_url": "string", + "device_flow": true, + "display_icon": "string", + "display_name": "string", + "id": "string", + "no_refresh": true, + "regex": "string", + "scopes": ["string"], + "token_url": "string", + "type": "string", + "validate_url": "string" + } + ] + }, + "external_token_encryption_keys": ["string"], + "healthcheck": { + "refresh": 0, + "threshold_database": 0 + }, + "http_address": "string", + "in_memory_database": true, + "job_hang_detector_interval": 0, + "logging": { + "human": "string", + "json": "string", + "log_filter": ["string"], + "stackdriver": "string" + }, + "metrics_cache_refresh_interval": 0, + "notifications": { + "dispatch_timeout": 0, + "email": { + "auth": { + "identity": "string", + "password": "string", + "password_file": "string", + "username": "string" + }, + "force_tls": true, + "from": "string", + "hello": "string", + "smarthost": { + "host": "string", + "port": "string" + }, + "tls": { + "ca_file": "string", + "cert_file": "string", + "insecure_skip_verify": true, + "key_file": "string", + "server_name": "string", + "start_tls": true + } + }, + "fetch_interval": 0, + "lease_count": 0, + "lease_period": 0, + "max_send_attempts": 0, + "method": "string", + "retry_interval": 0, + "sync_buffer_size": 0, + "sync_interval": 0, + "webhook": { + "endpoint": { + "forceQuery": true, + "fragment": "string", + "host": "string", + "omitHost": true, + "opaque": "string", + "path": "string", + "rawFragment": "string", + "rawPath": "string", + "rawQuery": "string", + "scheme": "string", + "user": {} + } + } + }, + "oauth2": { + "github": { + "allow_everyone": true, + "allow_signups": true, + "allowed_orgs": ["string"], + "allowed_teams": ["string"], + "client_id": "string", + "client_secret": "string", + "enterprise_base_url": "string" + } + }, + "oidc": { + "allow_signups": true, + "auth_url_params": {}, + "client_cert_file": "string", + "client_id": "string", + "client_key_file": "string", + "client_secret": "string", + "email_domain": ["string"], + "email_field": "string", + "group_allow_list": ["string"], + "group_auto_create": true, + "group_mapping": {}, + "group_regex_filter": {}, + "groups_field": "string", + "icon_url": { + "forceQuery": true, + "fragment": "string", + "host": "string", + "omitHost": true, + "opaque": "string", + "path": "string", + "rawFragment": "string", + "rawPath": "string", + "rawQuery": "string", + "scheme": "string", + "user": {} + }, + "ignore_email_verified": true, + "ignore_user_info": true, + "issuer_url": "string", + "name_field": "string", + "scopes": ["string"], + "sign_in_text": "string", + "signups_disabled_text": "string", + "skip_issuer_checks": true, + "user_role_field": "string", + "user_role_mapping": {}, + "user_roles_default": ["string"], + "username_field": "string" + }, + "pg_auth": "string", + "pg_connection_url": "string", + "pprof": { + "address": { + "host": "string", + "port": "string" + }, + "enable": true + }, + "prometheus": { + "address": { + "host": "string", + "port": "string" + }, + "aggregate_agent_stats_by": ["string"], + "collect_agent_stats": true, + "collect_db_metrics": true, + "enable": true + }, + "provisioner": { + "daemon_poll_interval": 0, + "daemon_poll_jitter": 0, + "daemon_psk": "string", + "daemon_types": ["string"], + "daemons": 0, + "force_cancel_interval": 0 + }, + "proxy_health_status_interval": 0, + "proxy_trusted_headers": ["string"], + "proxy_trusted_origins": ["string"], + "rate_limit": { + "api": 0, + "disable_all": true + }, + "redirect_to_access_url": true, + "scim_api_key": "string", + "secure_auth_cookie": true, + "session_lifetime": { + "default_duration": 0, + "disable_expiry_refresh": true, + "max_token_lifetime": 0 + }, + "ssh_keygen_algorithm": "string", + "strict_transport_security": 0, + "strict_transport_security_options": ["string"], + "support": { + "links": { + "value": [ + { + "icon": "bug", + "name": "string", + "target": "string" + } + ] + } + }, + "swagger": { + "enable": true + }, + "telemetry": { + "enable": true, + "trace": true, + "url": { + "forceQuery": true, + "fragment": "string", + "host": "string", + "omitHost": true, + "opaque": "string", + "path": "string", + "rawFragment": "string", + "rawPath": "string", + "rawQuery": "string", + "scheme": "string", + "user": {} + } + }, + "terms_of_service_url": "string", + "tls": { + "address": { + "host": "string", + "port": "string" + }, + "allow_insecure_ciphers": true, + "cert_file": ["string"], + "client_auth": "string", + "client_ca_file": "string", + "client_cert_file": "string", + "client_key_file": "string", + "enable": true, + "key_file": ["string"], + "min_version": "string", + "redirect_http": true, + "supported_ciphers": ["string"] + }, + "trace": { + "capture_logs": true, + "data_dog": true, + "enable": true, + "honeycomb_api_key": "string" + }, + "update_check": true, + "user_quiet_hours_schedule": { + "allow_user_custom": true, + "default_schedule": "string" + }, + "verbose": true, + "web_terminal_renderer": "string", + "wgtunnel_host": "string", + "wildcard_access_url": "string", + "write_config": true + }, + "options": [ + { + "annotations": { + "property1": "string", + "property2": "string" + }, + "default": "string", + "description": "string", + "env": "string", + "flag": "string", + "flag_shorthand": "string", + "group": { + "description": "string", + "name": "string", + "parent": { + "description": "string", + "name": "string", + "parent": {}, + "yaml": "string" + }, + "yaml": "string" + }, + "hidden": true, + "name": "string", + "required": true, + "use_instead": [{}], + "value": null, + "value_source": "", + "yaml": "string" + } + ] } ``` @@ -525,11 +525,11 @@ curl -X GET http://coder-server:8080/api/v2/deployment/ssh \ ```json { - "hostname_prefix": "string", - "ssh_config_options": { - "property1": "string", - "property2": "string" - } + "hostname_prefix": "string", + "ssh_config_options": { + "property1": "string", + "property2": "string" + } } ``` @@ -560,28 +560,28 @@ curl -X GET http://coder-server:8080/api/v2/deployment/stats \ ```json { - "aggregated_from": "2019-08-24T14:15:22Z", - "collected_at": "2019-08-24T14:15:22Z", - "next_update_at": "2019-08-24T14:15:22Z", - "session_count": { - "jetbrains": 0, - "reconnecting_pty": 0, - "ssh": 0, - "vscode": 0 - }, - "workspaces": { - "building": 0, - "connection_latency_ms": { - "p50": 0, - "p95": 0 - }, - "failed": 0, - "pending": 0, - "running": 0, - "rx_bytes": 0, - "stopped": 0, - "tx_bytes": 0 - } + "aggregated_from": "2019-08-24T14:15:22Z", + "collected_at": "2019-08-24T14:15:22Z", + "next_update_at": "2019-08-24T14:15:22Z", + "session_count": { + "jetbrains": 0, + "reconnecting_pty": 0, + "ssh": 0, + "vscode": 0 + }, + "workspaces": { + "building": 0, + "connection_latency_ms": { + "p50": 0, + "p95": 0 + }, + "failed": 0, + "pending": 0, + "running": 0, + "rx_bytes": 0, + "stopped": 0, + "tx_bytes": 0 + } } ``` @@ -685,9 +685,9 @@ curl -X GET http://coder-server:8080/api/v2/updatecheck \ ```json { - "current": true, - "url": "string", - "version": "string" + "current": true, + "url": "string", + "version": "string" } ``` @@ -722,7 +722,7 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/keys/tokens/tokenconfig ```json { - "max_token_lifetime": 0 + "max_token_lifetime": 0 } ``` diff --git a/docs/reference/api/git.md b/docs/reference/api/git.md index 929ab3e868..0200421ec2 100644 --- a/docs/reference/api/git.md +++ b/docs/reference/api/git.md @@ -19,13 +19,13 @@ curl -X GET http://coder-server:8080/api/v2/external-auth \ ```json { - "authenticated": true, - "created_at": "2019-08-24T14:15:22Z", - "expires": "2019-08-24T14:15:22Z", - "has_refresh_token": true, - "provider_id": "string", - "updated_at": "2019-08-24T14:15:22Z", - "validate_error": "string" + "authenticated": true, + "created_at": "2019-08-24T14:15:22Z", + "expires": "2019-08-24T14:15:22Z", + "has_refresh_token": true, + "provider_id": "string", + "updated_at": "2019-08-24T14:15:22Z", + "validate_error": "string" } ``` @@ -62,31 +62,31 @@ curl -X GET http://coder-server:8080/api/v2/external-auth/{externalauth} \ ```json { - "app_install_url": "string", - "app_installable": true, - "authenticated": true, - "device": true, - "display_name": "string", - "installations": [ - { - "account": { - "avatar_url": "string", - "id": 0, - "login": "string", - "name": "string", - "profile_url": "string" - }, - "configure_url": "string", - "id": 0 - } - ], - "user": { - "avatar_url": "string", - "id": 0, - "login": "string", - "name": "string", - "profile_url": "string" - } + "app_install_url": "string", + "app_installable": true, + "authenticated": true, + "device": true, + "display_name": "string", + "installations": [ + { + "account": { + "avatar_url": "string", + "id": 0, + "login": "string", + "name": "string", + "profile_url": "string" + }, + "configure_url": "string", + "id": 0 + } + ], + "user": { + "avatar_url": "string", + "id": 0, + "login": "string", + "name": "string", + "profile_url": "string" + } } ``` @@ -149,11 +149,11 @@ curl -X GET http://coder-server:8080/api/v2/external-auth/{externalauth}/device ```json { - "device_code": "string", - "expires_in": 0, - "interval": 0, - "user_code": "string", - "verification_uri": "string" + "device_code": "string", + "expires_in": 0, + "interval": 0, + "user_code": "string", + "verification_uri": "string" } ``` diff --git a/docs/reference/api/insights.md b/docs/reference/api/insights.md index eb1a7679a6..d9bb2327a9 100644 --- a/docs/reference/api/insights.md +++ b/docs/reference/api/insights.md @@ -25,13 +25,13 @@ curl -X GET http://coder-server:8080/api/v2/insights/daus?tz_offset=0 \ ```json { - "entries": [ - { - "amount": 0, - "date": "string" - } - ], - "tz_hour_offset": 0 + "entries": [ + { + "amount": 0, + "date": "string" + } + ], + "tz_hour_offset": 0 } ``` @@ -78,55 +78,55 @@ curl -X GET http://coder-server:8080/api/v2/insights/templates?start_time=2019-0 ```json { - "interval_reports": [ - { - "active_users": 14, - "end_time": "2019-08-24T14:15:22Z", - "interval": "week", - "start_time": "2019-08-24T14:15:22Z", - "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"] - } - ], - "report": { - "active_users": 22, - "apps_usage": [ - { - "display_name": "Visual Studio Code", - "icon": "string", - "seconds": 80500, - "slug": "vscode", - "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "times_used": 2, - "type": "builtin" - } - ], - "end_time": "2019-08-24T14:15:22Z", - "parameters_usage": [ - { - "description": "string", - "display_name": "string", - "name": "string", - "options": [ - { - "description": "string", - "icon": "string", - "name": "string", - "value": "string" - } - ], - "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "type": "string", - "values": [ - { - "count": 0, - "value": "string" - } - ] - } - ], - "start_time": "2019-08-24T14:15:22Z", - "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"] - } + "interval_reports": [ + { + "active_users": 14, + "end_time": "2019-08-24T14:15:22Z", + "interval": "week", + "start_time": "2019-08-24T14:15:22Z", + "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"] + } + ], + "report": { + "active_users": 22, + "apps_usage": [ + { + "display_name": "Visual Studio Code", + "icon": "string", + "seconds": 80500, + "slug": "vscode", + "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "times_used": 2, + "type": "builtin" + } + ], + "end_time": "2019-08-24T14:15:22Z", + "parameters_usage": [ + { + "description": "string", + "display_name": "string", + "name": "string", + "options": [ + { + "description": "string", + "icon": "string", + "name": "string", + "value": "string" + } + ], + "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "type": "string", + "values": [ + { + "count": 0, + "value": "string" + } + ] + } + ], + "start_time": "2019-08-24T14:15:22Z", + "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"] + } } ``` @@ -165,20 +165,20 @@ curl -X GET http://coder-server:8080/api/v2/insights/user-activity?start_time=20 ```json { - "report": { - "end_time": "2019-08-24T14:15:22Z", - "start_time": "2019-08-24T14:15:22Z", - "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "users": [ - { - "avatar_url": "http://example.com", - "seconds": 80500, - "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5", - "username": "string" - } - ] - } + "report": { + "end_time": "2019-08-24T14:15:22Z", + "start_time": "2019-08-24T14:15:22Z", + "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "users": [ + { + "avatar_url": "http://example.com", + "seconds": 80500, + "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5", + "username": "string" + } + ] + } } ``` @@ -217,23 +217,23 @@ curl -X GET http://coder-server:8080/api/v2/insights/user-latency?start_time=201 ```json { - "report": { - "end_time": "2019-08-24T14:15:22Z", - "start_time": "2019-08-24T14:15:22Z", - "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "users": [ - { - "avatar_url": "http://example.com", - "latency_ms": { - "p50": 31.312, - "p95": 119.832 - }, - "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5", - "username": "string" - } - ] - } + "report": { + "end_time": "2019-08-24T14:15:22Z", + "start_time": "2019-08-24T14:15:22Z", + "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "users": [ + { + "avatar_url": "http://example.com", + "latency_ms": { + "p50": 31.312, + "p95": 119.832 + }, + "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5", + "username": "string" + } + ] + } } ``` diff --git a/docs/reference/api/members.md b/docs/reference/api/members.md index 87b78e2343..e084ae1abe 100644 --- a/docs/reference/api/members.md +++ b/docs/reference/api/members.md @@ -25,30 +25,30 @@ curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/members ```json [ - { - "avatar_url": "string", - "created_at": "2019-08-24T14:15:22Z", - "email": "string", - "global_roles": [ - { - "display_name": "string", - "name": "string", - "organization_id": "string" - } - ], - "name": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "roles": [ - { - "display_name": "string", - "name": "string", - "organization_id": "string" - } - ], - "updated_at": "2019-08-24T14:15:22Z", - "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5", - "username": "string" - } + { + "avatar_url": "string", + "created_at": "2019-08-24T14:15:22Z", + "email": "string", + "global_roles": [ + { + "display_name": "string", + "name": "string", + "organization_id": "string" + } + ], + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "roles": [ + { + "display_name": "string", + "name": "string", + "organization_id": "string" + } + ], + "updated_at": "2019-08-24T14:15:22Z", + "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5", + "username": "string" + } ] ``` @@ -106,34 +106,34 @@ curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/members ```json [ - { - "assignable": true, - "built_in": true, - "display_name": "string", - "name": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "organization_permissions": [ - { - "action": "application_connect", - "negate": true, - "resource_type": "*" - } - ], - "site_permissions": [ - { - "action": "application_connect", - "negate": true, - "resource_type": "*" - } - ], - "user_permissions": [ - { - "action": "application_connect", - "negate": true, - "resource_type": "*" - } - ] - } + { + "assignable": true, + "built_in": true, + "display_name": "string", + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "organization_permissions": [ + { + "action": "application_connect", + "negate": true, + "resource_type": "*" + } + ], + "site_permissions": [ + { + "action": "application_connect", + "negate": true, + "resource_type": "*" + } + ], + "user_permissions": [ + { + "action": "application_connect", + "negate": true, + "resource_type": "*" + } + ] + } ] ``` @@ -229,29 +229,29 @@ curl -X PUT http://coder-server:8080/api/v2/organizations/{organization}/members ```json { - "display_name": "string", - "name": "string", - "organization_permissions": [ - { - "action": "application_connect", - "negate": true, - "resource_type": "*" - } - ], - "site_permissions": [ - { - "action": "application_connect", - "negate": true, - "resource_type": "*" - } - ], - "user_permissions": [ - { - "action": "application_connect", - "negate": true, - "resource_type": "*" - } - ] + "display_name": "string", + "name": "string", + "organization_permissions": [ + { + "action": "application_connect", + "negate": true, + "resource_type": "*" + } + ], + "site_permissions": [ + { + "action": "application_connect", + "negate": true, + "resource_type": "*" + } + ], + "user_permissions": [ + { + "action": "application_connect", + "negate": true, + "resource_type": "*" + } + ] } ``` @@ -268,32 +268,32 @@ curl -X PUT http://coder-server:8080/api/v2/organizations/{organization}/members ```json [ - { - "display_name": "string", - "name": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "organization_permissions": [ - { - "action": "application_connect", - "negate": true, - "resource_type": "*" - } - ], - "site_permissions": [ - { - "action": "application_connect", - "negate": true, - "resource_type": "*" - } - ], - "user_permissions": [ - { - "action": "application_connect", - "negate": true, - "resource_type": "*" - } - ] - } + { + "display_name": "string", + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "organization_permissions": [ + { + "action": "application_connect", + "negate": true, + "resource_type": "*" + } + ], + "site_permissions": [ + { + "action": "application_connect", + "negate": true, + "resource_type": "*" + } + ], + "user_permissions": [ + { + "action": "application_connect", + "negate": true, + "resource_type": "*" + } + ] + } ] ``` @@ -387,29 +387,29 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/member ```json { - "display_name": "string", - "name": "string", - "organization_permissions": [ - { - "action": "application_connect", - "negate": true, - "resource_type": "*" - } - ], - "site_permissions": [ - { - "action": "application_connect", - "negate": true, - "resource_type": "*" - } - ], - "user_permissions": [ - { - "action": "application_connect", - "negate": true, - "resource_type": "*" - } - ] + "display_name": "string", + "name": "string", + "organization_permissions": [ + { + "action": "application_connect", + "negate": true, + "resource_type": "*" + } + ], + "site_permissions": [ + { + "action": "application_connect", + "negate": true, + "resource_type": "*" + } + ], + "user_permissions": [ + { + "action": "application_connect", + "negate": true, + "resource_type": "*" + } + ] } ``` @@ -426,32 +426,32 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/member ```json [ - { - "display_name": "string", - "name": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "organization_permissions": [ - { - "action": "application_connect", - "negate": true, - "resource_type": "*" - } - ], - "site_permissions": [ - { - "action": "application_connect", - "negate": true, - "resource_type": "*" - } - ], - "user_permissions": [ - { - "action": "application_connect", - "negate": true, - "resource_type": "*" - } - ] - } + { + "display_name": "string", + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "organization_permissions": [ + { + "action": "application_connect", + "negate": true, + "resource_type": "*" + } + ], + "site_permissions": [ + { + "action": "application_connect", + "negate": true, + "resource_type": "*" + } + ], + "user_permissions": [ + { + "action": "application_connect", + "negate": true, + "resource_type": "*" + } + ] + } ] ``` @@ -553,32 +553,32 @@ curl -X DELETE http://coder-server:8080/api/v2/organizations/{organization}/memb ```json [ - { - "display_name": "string", - "name": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "organization_permissions": [ - { - "action": "application_connect", - "negate": true, - "resource_type": "*" - } - ], - "site_permissions": [ - { - "action": "application_connect", - "negate": true, - "resource_type": "*" - } - ], - "user_permissions": [ - { - "action": "application_connect", - "negate": true, - "resource_type": "*" - } - ] - } + { + "display_name": "string", + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "organization_permissions": [ + { + "action": "application_connect", + "negate": true, + "resource_type": "*" + } + ], + "site_permissions": [ + { + "action": "application_connect", + "negate": true, + "resource_type": "*" + } + ], + "user_permissions": [ + { + "action": "application_connect", + "negate": true, + "resource_type": "*" + } + ] + } ] ``` @@ -680,17 +680,17 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/member ```json { - "created_at": "2019-08-24T14:15:22Z", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "roles": [ - { - "display_name": "string", - "name": "string", - "organization_id": "string" - } - ], - "updated_at": "2019-08-24T14:15:22Z", - "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5" + "created_at": "2019-08-24T14:15:22Z", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "roles": [ + { + "display_name": "string", + "name": "string", + "organization_id": "string" + } + ], + "updated_at": "2019-08-24T14:15:22Z", + "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5" } ``` @@ -747,7 +747,7 @@ curl -X PUT http://coder-server:8080/api/v2/organizations/{organization}/members ```json { - "roles": ["string"] + "roles": ["string"] } ``` @@ -765,17 +765,17 @@ curl -X PUT http://coder-server:8080/api/v2/organizations/{organization}/members ```json { - "created_at": "2019-08-24T14:15:22Z", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "roles": [ - { - "display_name": "string", - "name": "string", - "organization_id": "string" - } - ], - "updated_at": "2019-08-24T14:15:22Z", - "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5" + "created_at": "2019-08-24T14:15:22Z", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "roles": [ + { + "display_name": "string", + "name": "string", + "organization_id": "string" + } + ], + "updated_at": "2019-08-24T14:15:22Z", + "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5" } ``` @@ -806,34 +806,34 @@ curl -X GET http://coder-server:8080/api/v2/users/roles \ ```json [ - { - "assignable": true, - "built_in": true, - "display_name": "string", - "name": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "organization_permissions": [ - { - "action": "application_connect", - "negate": true, - "resource_type": "*" - } - ], - "site_permissions": [ - { - "action": "application_connect", - "negate": true, - "resource_type": "*" - } - ], - "user_permissions": [ - { - "action": "application_connect", - "negate": true, - "resource_type": "*" - } - ] - } + { + "assignable": true, + "built_in": true, + "display_name": "string", + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "organization_permissions": [ + { + "action": "application_connect", + "negate": true, + "resource_type": "*" + } + ], + "site_permissions": [ + { + "action": "application_connect", + "negate": true, + "resource_type": "*" + } + ], + "user_permissions": [ + { + "action": "application_connect", + "negate": true, + "resource_type": "*" + } + ] + } ] ``` diff --git a/docs/reference/api/notifications.md b/docs/reference/api/notifications.md index 528153ebd1..21cad113ad 100644 --- a/docs/reference/api/notifications.md +++ b/docs/reference/api/notifications.md @@ -19,10 +19,10 @@ curl -X GET http://coder-server:8080/api/v2/notifications/dispatch-methods \ ```json [ - { - "available": ["string"], - "default": "string" - } + { + "available": ["string"], + "default": "string" + } ] ``` @@ -63,7 +63,7 @@ curl -X GET http://coder-server:8080/api/v2/notifications/settings \ ```json { - "notifier_paused": true + "notifier_paused": true } ``` @@ -93,7 +93,7 @@ curl -X PUT http://coder-server:8080/api/v2/notifications/settings \ ```json { - "notifier_paused": true + "notifier_paused": true } ``` @@ -109,7 +109,7 @@ curl -X PUT http://coder-server:8080/api/v2/notifications/settings \ ```json { - "notifier_paused": true + "notifier_paused": true } ``` @@ -141,16 +141,16 @@ curl -X GET http://coder-server:8080/api/v2/notifications/templates/system \ ```json [ - { - "actions": "string", - "body_template": "string", - "group": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "kind": "string", - "method": "string", - "name": "string", - "title_template": "string" - } + { + "actions": "string", + "body_template": "string", + "group": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "kind": "string", + "method": "string", + "name": "string", + "title_template": "string" + } ] ``` @@ -203,11 +203,11 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/notifications/preferenc ```json [ - { - "disabled": true, - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "updated_at": "2019-08-24T14:15:22Z" - } + { + "disabled": true, + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "updated_at": "2019-08-24T14:15:22Z" + } ] ``` @@ -248,10 +248,10 @@ curl -X PUT http://coder-server:8080/api/v2/users/{user}/notifications/preferenc ```json { - "template_disabled_map": { - "property1": true, - "property2": true - } + "template_disabled_map": { + "property1": true, + "property2": true + } } ``` @@ -268,11 +268,11 @@ curl -X PUT http://coder-server:8080/api/v2/users/{user}/notifications/preferenc ```json [ - { - "disabled": true, - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "updated_at": "2019-08-24T14:15:22Z" - } + { + "disabled": true, + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "updated_at": "2019-08-24T14:15:22Z" + } ] ``` diff --git a/docs/reference/api/organizations.md b/docs/reference/api/organizations.md index 4c4f49bb9d..e398d8e7c0 100644 --- a/docs/reference/api/organizations.md +++ b/docs/reference/api/organizations.md @@ -18,7 +18,7 @@ curl -X POST http://coder-server:8080/api/v2/licenses \ ```json { - "license": "string" + "license": "string" } ``` @@ -34,10 +34,10 @@ curl -X POST http://coder-server:8080/api/v2/licenses \ ```json { - "claims": {}, - "id": 0, - "uploaded_at": "2019-08-24T14:15:22Z", - "uuid": "095be615-a8ad-4c33-8e9c-c7612fbf6c9f" + "claims": {}, + "id": 0, + "uploaded_at": "2019-08-24T14:15:22Z", + "uuid": "095be615-a8ad-4c33-8e9c-c7612fbf6c9f" } ``` @@ -68,14 +68,14 @@ curl -X POST http://coder-server:8080/api/v2/licenses/refresh-entitlements \ ```json { - "detail": "string", - "message": "string", - "validations": [ - { - "detail": "string", - "field": "string" - } - ] + "detail": "string", + "message": "string", + "validations": [ + { + "detail": "string", + "field": "string" + } + ] } ``` @@ -106,16 +106,16 @@ curl -X GET http://coder-server:8080/api/v2/organizations \ ```json [ - { - "created_at": "2019-08-24T14:15:22Z", - "description": "string", - "display_name": "string", - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "is_default": true, - "name": "string", - "updated_at": "2019-08-24T14:15:22Z" - } + { + "created_at": "2019-08-24T14:15:22Z", + "description": "string", + "display_name": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "is_default": true, + "name": "string", + "updated_at": "2019-08-24T14:15:22Z" + } ] ``` @@ -161,10 +161,10 @@ curl -X POST http://coder-server:8080/api/v2/organizations \ ```json { - "description": "string", - "display_name": "string", - "icon": "string", - "name": "string" + "description": "string", + "display_name": "string", + "icon": "string", + "name": "string" } ``` @@ -180,14 +180,14 @@ curl -X POST http://coder-server:8080/api/v2/organizations \ ```json { - "created_at": "2019-08-24T14:15:22Z", - "description": "string", - "display_name": "string", - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "is_default": true, - "name": "string", - "updated_at": "2019-08-24T14:15:22Z" + "created_at": "2019-08-24T14:15:22Z", + "description": "string", + "display_name": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "is_default": true, + "name": "string", + "updated_at": "2019-08-24T14:15:22Z" } ``` @@ -224,14 +224,14 @@ curl -X GET http://coder-server:8080/api/v2/organizations/{organization} \ ```json { - "created_at": "2019-08-24T14:15:22Z", - "description": "string", - "display_name": "string", - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "is_default": true, - "name": "string", - "updated_at": "2019-08-24T14:15:22Z" + "created_at": "2019-08-24T14:15:22Z", + "description": "string", + "display_name": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "is_default": true, + "name": "string", + "updated_at": "2019-08-24T14:15:22Z" } ``` @@ -268,14 +268,14 @@ curl -X DELETE http://coder-server:8080/api/v2/organizations/{organization} \ ```json { - "detail": "string", - "message": "string", - "validations": [ - { - "detail": "string", - "field": "string" - } - ] + "detail": "string", + "message": "string", + "validations": [ + { + "detail": "string", + "field": "string" + } + ] } ``` @@ -305,10 +305,10 @@ curl -X PATCH http://coder-server:8080/api/v2/organizations/{organization} \ ```json { - "description": "string", - "display_name": "string", - "icon": "string", - "name": "string" + "description": "string", + "display_name": "string", + "icon": "string", + "name": "string" } ``` @@ -325,14 +325,14 @@ curl -X PATCH http://coder-server:8080/api/v2/organizations/{organization} \ ```json { - "created_at": "2019-08-24T14:15:22Z", - "description": "string", - "display_name": "string", - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "is_default": true, - "name": "string", - "updated_at": "2019-08-24T14:15:22Z" + "created_at": "2019-08-24T14:15:22Z", + "description": "string", + "display_name": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "is_default": true, + "name": "string", + "updated_at": "2019-08-24T14:15:22Z" } ``` diff --git a/docs/reference/api/portsharing.md b/docs/reference/api/portsharing.md index 179ab63f31..dbd81cd9a2 100644 --- a/docs/reference/api/portsharing.md +++ b/docs/reference/api/portsharing.md @@ -17,8 +17,8 @@ curl -X DELETE http://coder-server:8080/api/v2/workspaces/{workspace}/port-share ```json { - "agent_name": "string", - "port": 0 + "agent_name": "string", + "port": 0 } ``` @@ -55,10 +55,10 @@ curl -X POST http://coder-server:8080/api/v2/workspaces/{workspace}/port-share \ ```json { - "agent_name": "string", - "port": 0, - "protocol": "http", - "share_level": "owner" + "agent_name": "string", + "port": 0, + "protocol": "http", + "share_level": "owner" } ``` @@ -75,11 +75,11 @@ curl -X POST http://coder-server:8080/api/v2/workspaces/{workspace}/port-share \ ```json { - "agent_name": "string", - "port": 0, - "protocol": "http", - "share_level": "owner", - "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9" + "agent_name": "string", + "port": 0, + "protocol": "http", + "share_level": "owner", + "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9" } ``` diff --git a/docs/reference/api/schemas.md b/docs/reference/api/schemas.md index cb7c88af83..27d65ad5ec 100644 --- a/docs/reference/api/schemas.md +++ b/docs/reference/api/schemas.md @@ -4,8 +4,8 @@ ```json { - "document": "string", - "signature": "string" + "document": "string", + "signature": "string" } ``` @@ -20,7 +20,7 @@ ```json { - "session_token": "string" + "session_token": "string" } ``` @@ -34,8 +34,8 @@ ```json { - "encoding": "string", - "signature": "string" + "encoding": "string", + "signature": "string" } ``` @@ -50,12 +50,12 @@ ```json { - "access_token": "string", - "password": "string", - "token_extra": {}, - "type": "string", - "url": "string", - "username": "string" + "access_token": "string", + "password": "string", + "token_extra": {}, + "type": "string", + "url": "string", + "username": "string" } ``` @@ -74,8 +74,8 @@ ```json { - "private_key": "string", - "public_key": "string" + "private_key": "string", + "public_key": "string" } ``` @@ -90,7 +90,7 @@ ```json { - "json_web_token": "string" + "json_web_token": "string" } ``` @@ -104,9 +104,9 @@ ```json { - "created_at": "string", - "level": "trace", - "output": "string" + "created_at": "string", + "level": "trace", + "output": "string" } ``` @@ -122,14 +122,14 @@ ```json { - "log_source_id": "string", - "logs": [ - { - "created_at": "string", - "level": "trace", - "output": "string" - } - ] + "log_source_id": "string", + "logs": [ + { + "created_at": "string", + "level": "trace", + "output": "string" + } + ] } ``` @@ -144,9 +144,9 @@ ```json { - "display_name": "string", - "icon": "string", - "id": "string" + "display_name": "string", + "icon": "string", + "id": "string" } ``` @@ -162,26 +162,26 @@ ```json { - "active": true, - "emails": [ - { - "display": "string", - "primary": true, - "type": "string", - "value": "user@example.com" - } - ], - "groups": [null], - "id": "string", - "meta": { - "resourceType": "string" - }, - "name": { - "familyName": "string", - "givenName": "string" - }, - "schemas": ["string"], - "userName": "string" + "active": true, + "emails": [ + { + "display": "string", + "primary": true, + "type": "string", + "value": "user@example.com" + } + ], + "groups": [null], + "id": "string", + "meta": { + "resourceType": "string" + }, + "name": { + "familyName": "string", + "givenName": "string" + }, + "schemas": ["string"], + "userName": "string" } ``` @@ -209,7 +209,7 @@ ```json { - "csp-report": {} + "csp-report": {} } ``` @@ -223,48 +223,48 @@ ```json { - "groups": [ - { - "avatar_url": "string", - "display_name": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "members": [ - { - "avatar_url": "http://example.com", - "created_at": "2019-08-24T14:15:22Z", - "email": "user@example.com", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "last_seen_at": "2019-08-24T14:15:22Z", - "login_type": "", - "name": "string", - "status": "active", - "theme_preference": "string", - "updated_at": "2019-08-24T14:15:22Z", - "username": "string" - } - ], - "name": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "quota_allowance": 0, - "source": "user", - "total_member_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", - "login_type": "", - "name": "string", - "status": "active", - "theme_preference": "string", - "updated_at": "2019-08-24T14:15:22Z", - "username": "string" - } - ] + "groups": [ + { + "avatar_url": "string", + "display_name": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "members": [ + { + "avatar_url": "http://example.com", + "created_at": "2019-08-24T14:15:22Z", + "email": "user@example.com", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "last_seen_at": "2019-08-24T14:15:22Z", + "login_type": "", + "name": "string", + "status": "active", + "theme_preference": "string", + "updated_at": "2019-08-24T14:15:22Z", + "username": "string" + } + ], + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "quota_allowance": 0, + "source": "user", + "total_member_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", + "login_type": "", + "name": "string", + "status": "active", + "theme_preference": "string", + "updated_at": "2019-08-24T14:15:22Z", + "username": "string" + } + ] } ``` @@ -279,16 +279,16 @@ ```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", - "token_name": "string", - "updated_at": "2019-08-24T14:15:22Z", - "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5" + "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", + "token_name": "string", + "updated_at": "2019-08-24T14:15:22Z", + "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5" } ``` @@ -337,7 +337,7 @@ ```json { - "license": "string" + "license": "string" } ``` @@ -367,7 +367,7 @@ ```json { - "host": "string" + "host": "string" } ``` @@ -381,27 +381,27 @@ ```json { - "announcement_banners": [ - { - "background_color": "string", - "enabled": true, - "message": "string" - } - ], - "application_name": "string", - "logo_url": "string", - "service_banner": { - "background_color": "string", - "enabled": true, - "message": "string" - }, - "support_links": [ - { - "icon": "bug", - "name": "string", - "target": "string" - } - ] + "announcement_banners": [ + { + "background_color": "string", + "enabled": true, + "message": "string" + } + ], + "application_name": "string", + "logo_url": "string", + "service_banner": { + "background_color": "string", + "enabled": true, + "message": "string" + }, + "support_links": [ + { + "icon": "bug", + "name": "string", + "target": "string" + } + ] } ``` @@ -419,7 +419,7 @@ ```json { - "all": true + "all": true } ``` @@ -433,32 +433,32 @@ ```json { - "assignable": true, - "built_in": true, - "display_name": "string", - "name": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "organization_permissions": [ - { - "action": "application_connect", - "negate": true, - "resource_type": "*" - } - ], - "site_permissions": [ - { - "action": "application_connect", - "negate": true, - "resource_type": "*" - } - ], - "user_permissions": [ - { - "action": "application_connect", - "negate": true, - "resource_type": "*" - } - ] + "assignable": true, + "built_in": true, + "display_name": "string", + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "organization_permissions": [ + { + "action": "application_connect", + "negate": true, + "resource_type": "*" + } + ], + "site_permissions": [ + { + "action": "application_connect", + "negate": true, + "resource_type": "*" + } + ], + "user_permissions": [ + { + "action": "application_connect", + "negate": true, + "resource_type": "*" + } + ] } ``` @@ -500,16 +500,16 @@ ```json { - "property1": { - "new": null, - "old": null, - "secret": true - }, - "property2": { - "new": null, - "old": null, - "secret": true - } + "property1": { + "new": null, + "old": null, + "secret": true + }, + "property2": { + "new": null, + "old": null, + "secret": true + } } ``` @@ -523,9 +523,9 @@ ```json { - "new": null, - "old": null, - "secret": true + "new": null, + "old": null, + "secret": true } ``` @@ -541,61 +541,61 @@ ```json { - "action": "create", - "additional_fields": [0], - "description": "string", - "diff": { - "property1": { - "new": null, - "old": null, - "secret": true - }, - "property2": { - "new": null, - "old": null, - "secret": true - } - }, - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "ip": "string", - "is_deleted": true, - "organization": { - "display_name": "string", - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "name": "string" - }, - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "request_id": "266ea41d-adf5-480b-af50-15b940c2b846", - "resource_icon": "string", - "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", - "resource_link": "string", - "resource_target": "string", - "resource_type": "template", - "status_code": 0, - "time": "2019-08-24T14:15:22Z", - "user": { - "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", - "login_type": "", - "name": "string", - "organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "roles": [ - { - "display_name": "string", - "name": "string", - "organization_id": "string" - } - ], - "status": "active", - "theme_preference": "string", - "updated_at": "2019-08-24T14:15:22Z", - "username": "string" - }, - "user_agent": "string" + "action": "create", + "additional_fields": [0], + "description": "string", + "diff": { + "property1": { + "new": null, + "old": null, + "secret": true + }, + "property2": { + "new": null, + "old": null, + "secret": true + } + }, + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "ip": "string", + "is_deleted": true, + "organization": { + "display_name": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "string" + }, + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "request_id": "266ea41d-adf5-480b-af50-15b940c2b846", + "resource_icon": "string", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", + "resource_link": "string", + "resource_target": "string", + "resource_type": "template", + "status_code": 0, + "time": "2019-08-24T14:15:22Z", + "user": { + "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", + "login_type": "", + "name": "string", + "organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "roles": [ + { + "display_name": "string", + "name": "string", + "organization_id": "string" + } + ], + "status": "active", + "theme_preference": "string", + "updated_at": "2019-08-24T14:15:22Z", + "username": "string" + }, + "user_agent": "string" } ``` @@ -627,66 +627,66 @@ ```json { - "audit_logs": [ - { - "action": "create", - "additional_fields": [0], - "description": "string", - "diff": { - "property1": { - "new": null, - "old": null, - "secret": true - }, - "property2": { - "new": null, - "old": null, - "secret": true - } - }, - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "ip": "string", - "is_deleted": true, - "organization": { - "display_name": "string", - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "name": "string" - }, - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "request_id": "266ea41d-adf5-480b-af50-15b940c2b846", - "resource_icon": "string", - "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", - "resource_link": "string", - "resource_target": "string", - "resource_type": "template", - "status_code": 0, - "time": "2019-08-24T14:15:22Z", - "user": { - "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", - "login_type": "", - "name": "string", - "organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "roles": [ - { - "display_name": "string", - "name": "string", - "organization_id": "string" - } - ], - "status": "active", - "theme_preference": "string", - "updated_at": "2019-08-24T14:15:22Z", - "username": "string" - }, - "user_agent": "string" - } - ], - "count": 0 + "audit_logs": [ + { + "action": "create", + "additional_fields": [0], + "description": "string", + "diff": { + "property1": { + "new": null, + "old": null, + "secret": true + }, + "property2": { + "new": null, + "old": null, + "secret": true + } + }, + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "ip": "string", + "is_deleted": true, + "organization": { + "display_name": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "string" + }, + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "request_id": "266ea41d-adf5-480b-af50-15b940c2b846", + "resource_icon": "string", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", + "resource_link": "string", + "resource_target": "string", + "resource_type": "template", + "status_code": 0, + "time": "2019-08-24T14:15:22Z", + "user": { + "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", + "login_type": "", + "name": "string", + "organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "roles": [ + { + "display_name": "string", + "name": "string", + "organization_id": "string" + } + ], + "status": "active", + "theme_preference": "string", + "updated_at": "2019-08-24T14:15:22Z", + "username": "string" + }, + "user_agent": "string" + } + ], + "count": 0 } ``` @@ -701,7 +701,7 @@ ```json { - "enabled": true + "enabled": true } ``` @@ -715,18 +715,18 @@ ```json { - "github": { - "enabled": true - }, - "oidc": { - "enabled": true, - "iconUrl": "string", - "signInText": "string" - }, - "password": { - "enabled": true - }, - "terms_of_service_url": "string" + "github": { + "enabled": true + }, + "oidc": { + "enabled": true, + "iconUrl": "string", + "signInText": "string" + }, + "password": { + "enabled": true + }, + "terms_of_service_url": "string" } ``` @@ -743,14 +743,14 @@ ```json { - "action": "create", - "object": { - "any_org": true, - "organization_id": "string", - "owner_id": "string", - "resource_id": "string", - "resource_type": "*" - } + "action": "create", + "object": { + "any_org": true, + "organization_id": "string", + "owner_id": "string", + "resource_id": "string", + "resource_type": "*" + } } ``` @@ -776,11 +776,11 @@ AuthorizationCheck is used to check if the currently authenticated user (or the ```json { - "any_org": true, - "organization_id": "string", - "owner_id": "string", - "resource_id": "string", - "resource_type": "*" + "any_org": true, + "organization_id": "string", + "owner_id": "string", + "resource_id": "string", + "resource_type": "*" } ``` @@ -800,28 +800,28 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in ```json { - "checks": { - "property1": { - "action": "create", - "object": { - "any_org": true, - "organization_id": "string", - "owner_id": "string", - "resource_id": "string", - "resource_type": "*" - } - }, - "property2": { - "action": "create", - "object": { - "any_org": true, - "organization_id": "string", - "owner_id": "string", - "resource_id": "string", - "resource_type": "*" - } - } - } + "checks": { + "property1": { + "action": "create", + "object": { + "any_org": true, + "organization_id": "string", + "owner_id": "string", + "resource_id": "string", + "resource_type": "*" + } + }, + "property2": { + "action": "create", + "object": { + "any_org": true, + "organization_id": "string", + "owner_id": "string", + "resource_id": "string", + "resource_type": "*" + } + } + } } ``` @@ -836,8 +836,8 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in ```json { - "property1": true, - "property2": true + "property1": true, + "property2": true } ``` @@ -866,9 +866,9 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in ```json { - "background_color": "string", - "enabled": true, - "message": "string" + "background_color": "string", + "enabled": true, + "message": "string" } ``` @@ -884,14 +884,14 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in ```json { - "agent_api_version": "string", - "dashboard_url": "string", - "deployment_id": "string", - "external_url": "string", - "telemetry": true, - "upgrade_message": "string", - "version": "string", - "workspace_proxy": true + "agent_api_version": "string", + "dashboard_url": "string", + "deployment_id": "string", + "external_url": "string", + "telemetry": true, + "upgrade_message": "string", + "version": "string", + "workspace_proxy": true } ``` @@ -928,8 +928,8 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in ```json { - "p50": 31.312, - "p95": 119.832 + "p50": 31.312, + "p95": 119.832 } ``` @@ -944,8 +944,8 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in ```json { - "password": "string", - "to_type": "" + "password": "string", + "to_type": "" } ``` @@ -960,20 +960,20 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in ```json { - "email": "string", - "name": "string", - "password": "string", - "trial": true, - "trial_info": { - "company_name": "string", - "country": "string", - "developers": "string", - "first_name": "string", - "job_title": "string", - "last_name": "string", - "phone_number": "string" - }, - "username": "string" + "email": "string", + "name": "string", + "password": "string", + "trial": true, + "trial_info": { + "company_name": "string", + "country": "string", + "developers": "string", + "first_name": "string", + "job_title": "string", + "last_name": "string", + "phone_number": "string" + }, + "username": "string" } ``` @@ -992,8 +992,8 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in ```json { - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5" + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5" } ``` @@ -1008,13 +1008,13 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in ```json { - "company_name": "string", - "country": "string", - "developers": "string", - "first_name": "string", - "job_title": "string", - "last_name": "string", - "phone_number": "string" + "company_name": "string", + "country": "string", + "developers": "string", + "first_name": "string", + "job_title": "string", + "last_name": "string", + "phone_number": "string" } ``` @@ -1034,10 +1034,10 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in ```json { - "avatar_url": "string", - "display_name": "string", - "name": "string", - "quota_allowance": 0 + "avatar_url": "string", + "display_name": "string", + "name": "string", + "quota_allowance": 0 } ``` @@ -1054,10 +1054,10 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in ```json { - "description": "string", - "display_name": "string", - "icon": "string", - "name": "string" + "description": "string", + "display_name": "string", + "icon": "string", + "name": "string" } ``` @@ -1074,7 +1074,7 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in ```json { - "key": "string" + "key": "string" } ``` @@ -1088,28 +1088,28 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in ```json { - "activity_bump_ms": 0, - "allow_user_autostart": true, - "allow_user_autostop": true, - "allow_user_cancel_workspace_jobs": true, - "autostart_requirement": { - "days_of_week": ["monday"] - }, - "autostop_requirement": { - "days_of_week": ["monday"], - "weeks": 0 - }, - "default_ttl_ms": 0, - "delete_ttl_ms": 0, - "description": "string", - "disable_everyone_group_access": true, - "display_name": "string", - "dormant_ttl_ms": 0, - "failure_ttl_ms": 0, - "icon": "string", - "name": "string", - "require_active_version": true, - "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1" + "activity_bump_ms": 0, + "allow_user_autostart": true, + "allow_user_autostop": true, + "allow_user_cancel_workspace_jobs": true, + "autostart_requirement": { + "days_of_week": ["monday"] + }, + "autostop_requirement": { + "days_of_week": ["monday"], + "weeks": 0 + }, + "default_ttl_ms": 0, + "delete_ttl_ms": 0, + "description": "string", + "disable_everyone_group_access": true, + "display_name": "string", + "dormant_ttl_ms": 0, + "failure_ttl_ms": 0, + "icon": "string", + "name": "string", + "require_active_version": true, + "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1" } ``` @@ -1140,19 +1140,19 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in ```json { - "rich_parameter_values": [ - { - "name": "string", - "value": "string" - } - ], - "user_variable_values": [ - { - "name": "string", - "value": "string" - } - ], - "workspace_name": "string" + "rich_parameter_values": [ + { + "name": "string", + "value": "string" + } + ], + "user_variable_values": [ + { + "name": "string", + "value": "string" + } + ], + "workspace_name": "string" } ``` @@ -1168,23 +1168,23 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in ```json { - "example_id": "string", - "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", - "message": "string", - "name": "string", - "provisioner": "terraform", - "storage_method": "file", - "tags": { - "property1": "string", - "property2": "string" - }, - "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", - "user_variable_values": [ - { - "name": "string", - "value": "string" - } - ] + "example_id": "string", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "message": "string", + "name": "string", + "provisioner": "terraform", + "storage_method": "file", + "tags": { + "property1": "string", + "property2": "string" + }, + "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", + "user_variable_values": [ + { + "name": "string", + "value": "string" + } + ] } ``` @@ -1215,13 +1215,13 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in ```json { - "action": "create", - "additional_fields": [0], - "build_reason": "autostart", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", - "resource_type": "template", - "time": "2019-08-24T14:15:22Z" + "action": "create", + "additional_fields": [0], + "build_reason": "autostart", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", + "resource_type": "template", + "time": "2019-08-24T14:15:22Z" } ``` @@ -1261,9 +1261,9 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in ```json { - "lifetime": 0, - "scope": "all", - "token_name": "string" + "lifetime": 0, + "scope": "all", + "token_name": "string" } ``` @@ -1286,13 +1286,13 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in ```json { - "disable_login": true, - "email": "user@example.com", - "login_type": "", - "name": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "password": "string", - "username": "string" + "disable_login": true, + "email": "user@example.com", + "login_type": "", + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "password": "string", + "username": "string" } ``` @@ -1312,18 +1312,18 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in ```json { - "dry_run": true, - "log_level": "debug", - "orphan": true, - "rich_parameter_values": [ - { - "name": "string", - "value": "string" - } - ], - "state": [0], - "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1", - "transition": "create" + "dry_run": true, + "log_level": "debug", + "orphan": true, + "rich_parameter_values": [ + { + "name": "string", + "value": "string" + } + ], + "state": [0], + "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1", + "transition": "create" } ``` @@ -1353,9 +1353,9 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in ```json { - "display_name": "string", - "icon": "string", - "name": "string" + "display_name": "string", + "icon": "string", + "name": "string" } ``` @@ -1371,18 +1371,18 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in ```json { - "automatic_updates": "always", - "autostart_schedule": "string", - "name": "string", - "rich_parameter_values": [ - { - "name": "string", - "value": "string" - } - ], - "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", - "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1", - "ttl_ms": 0 + "automatic_updates": "always", + "autostart_schedule": "string", + "name": "string", + "rich_parameter_values": [ + { + "name": "string", + "value": "string" + } + ], + "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", + "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1", + "ttl_ms": 0 } ``` @@ -1404,29 +1404,29 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "display_name": "string", - "name": "string", - "organization_permissions": [ - { - "action": "application_connect", - "negate": true, - "resource_type": "*" - } - ], - "site_permissions": [ - { - "action": "application_connect", - "negate": true, - "resource_type": "*" - } - ], - "user_permissions": [ - { - "action": "application_connect", - "negate": true, - "resource_type": "*" - } - ] + "display_name": "string", + "name": "string", + "organization_permissions": [ + { + "action": "application_connect", + "negate": true, + "resource_type": "*" + } + ], + "site_permissions": [ + { + "action": "application_connect", + "negate": true, + "resource_type": "*" + } + ], + "user_permissions": [ + { + "action": "application_connect", + "negate": true, + "resource_type": "*" + } + ] } ``` @@ -1444,8 +1444,8 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "amount": 0, - "date": "string" + "amount": 0, + "date": "string" } ``` @@ -1460,13 +1460,13 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "entries": [ - { - "amount": 0, - "date": "string" - } - ], - "tz_hour_offset": 0 + "entries": [ + { + "amount": 0, + "date": "string" + } + ], + "tz_hour_offset": 0 } ``` @@ -1481,32 +1481,32 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "config": { - "block_direct": true, - "force_websockets": true, - "path": "string", - "url": "string" - }, - "server": { - "enable": true, - "region_code": "string", - "region_id": 0, - "region_name": "string", - "relay_url": { - "forceQuery": true, - "fragment": "string", - "host": "string", - "omitHost": true, - "opaque": "string", - "path": "string", - "rawFragment": "string", - "rawPath": "string", - "rawQuery": "string", - "scheme": "string", - "user": {} - }, - "stun_addresses": ["string"] - } + "config": { + "block_direct": true, + "force_websockets": true, + "path": "string", + "url": "string" + }, + "server": { + "enable": true, + "region_code": "string", + "region_id": 0, + "region_name": "string", + "relay_url": { + "forceQuery": true, + "fragment": "string", + "host": "string", + "omitHost": true, + "opaque": "string", + "path": "string", + "rawFragment": "string", + "rawPath": "string", + "rawQuery": "string", + "scheme": "string", + "user": {} + }, + "stun_addresses": ["string"] + } } ``` @@ -1521,10 +1521,10 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "block_direct": true, - "force_websockets": true, - "path": "string", - "url": "string" + "block_direct": true, + "force_websockets": true, + "path": "string", + "url": "string" } ``` @@ -1541,8 +1541,8 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "latency_ms": 0, - "preferred": true + "latency_ms": 0, + "preferred": true } ``` @@ -1557,24 +1557,24 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "enable": true, - "region_code": "string", - "region_id": 0, - "region_name": "string", - "relay_url": { - "forceQuery": true, - "fragment": "string", - "host": "string", - "omitHost": true, - "opaque": "string", - "path": "string", - "rawFragment": "string", - "rawPath": "string", - "rawQuery": "string", - "scheme": "string", - "user": {} - }, - "stun_addresses": ["string"] + "enable": true, + "region_code": "string", + "region_id": 0, + "region_name": "string", + "relay_url": { + "forceQuery": true, + "fragment": "string", + "host": "string", + "omitHost": true, + "opaque": "string", + "path": "string", + "rawFragment": "string", + "rawPath": "string", + "rawQuery": "string", + "scheme": "string", + "user": {} + }, + "stun_addresses": ["string"] } ``` @@ -1593,9 +1593,9 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "allow_all_cors": true, - "allow_path_app_sharing": true, - "allow_path_app_site_owner_access": true + "allow_all_cors": true, + "allow_path_app_sharing": true, + "allow_path_app_site_owner_access": true } ``` @@ -1611,8 +1611,8 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "agent_name": "string", - "port": 0 + "agent_name": "string", + "port": 0 } ``` @@ -1627,377 +1627,377 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "config": { - "access_url": { - "forceQuery": true, - "fragment": "string", - "host": "string", - "omitHost": true, - "opaque": "string", - "path": "string", - "rawFragment": "string", - "rawPath": "string", - "rawQuery": "string", - "scheme": "string", - "user": {} - }, - "address": { - "host": "string", - "port": "string" - }, - "agent_fallback_troubleshooting_url": { - "forceQuery": true, - "fragment": "string", - "host": "string", - "omitHost": true, - "opaque": "string", - "path": "string", - "rawFragment": "string", - "rawPath": "string", - "rawQuery": "string", - "scheme": "string", - "user": {} - }, - "agent_stat_refresh_interval": 0, - "allow_workspace_renames": true, - "autobuild_poll_interval": 0, - "browser_only": true, - "cache_directory": "string", - "cli_upgrade_message": "string", - "config": "string", - "config_ssh": { - "deploymentName": "string", - "sshconfigOptions": ["string"] - }, - "dangerous": { - "allow_all_cors": true, - "allow_path_app_sharing": true, - "allow_path_app_site_owner_access": true - }, - "derp": { - "config": { - "block_direct": true, - "force_websockets": true, - "path": "string", - "url": "string" - }, - "server": { - "enable": true, - "region_code": "string", - "region_id": 0, - "region_name": "string", - "relay_url": { - "forceQuery": true, - "fragment": "string", - "host": "string", - "omitHost": true, - "opaque": "string", - "path": "string", - "rawFragment": "string", - "rawPath": "string", - "rawQuery": "string", - "scheme": "string", - "user": {} - }, - "stun_addresses": ["string"] - } - }, - "disable_owner_workspace_exec": true, - "disable_password_auth": true, - "disable_path_apps": true, - "docs_url": { - "forceQuery": true, - "fragment": "string", - "host": "string", - "omitHost": true, - "opaque": "string", - "path": "string", - "rawFragment": "string", - "rawPath": "string", - "rawQuery": "string", - "scheme": "string", - "user": {} - }, - "enable_terraform_debug_mode": true, - "experiments": ["string"], - "external_auth": { - "value": [ - { - "app_install_url": "string", - "app_installations_url": "string", - "auth_url": "string", - "client_id": "string", - "device_code_url": "string", - "device_flow": true, - "display_icon": "string", - "display_name": "string", - "id": "string", - "no_refresh": true, - "regex": "string", - "scopes": ["string"], - "token_url": "string", - "type": "string", - "validate_url": "string" - } - ] - }, - "external_token_encryption_keys": ["string"], - "healthcheck": { - "refresh": 0, - "threshold_database": 0 - }, - "http_address": "string", - "in_memory_database": true, - "job_hang_detector_interval": 0, - "logging": { - "human": "string", - "json": "string", - "log_filter": ["string"], - "stackdriver": "string" - }, - "metrics_cache_refresh_interval": 0, - "notifications": { - "dispatch_timeout": 0, - "email": { - "auth": { - "identity": "string", - "password": "string", - "password_file": "string", - "username": "string" - }, - "force_tls": true, - "from": "string", - "hello": "string", - "smarthost": { - "host": "string", - "port": "string" - }, - "tls": { - "ca_file": "string", - "cert_file": "string", - "insecure_skip_verify": true, - "key_file": "string", - "server_name": "string", - "start_tls": true - } - }, - "fetch_interval": 0, - "lease_count": 0, - "lease_period": 0, - "max_send_attempts": 0, - "method": "string", - "retry_interval": 0, - "sync_buffer_size": 0, - "sync_interval": 0, - "webhook": { - "endpoint": { - "forceQuery": true, - "fragment": "string", - "host": "string", - "omitHost": true, - "opaque": "string", - "path": "string", - "rawFragment": "string", - "rawPath": "string", - "rawQuery": "string", - "scheme": "string", - "user": {} - } - } - }, - "oauth2": { - "github": { - "allow_everyone": true, - "allow_signups": true, - "allowed_orgs": ["string"], - "allowed_teams": ["string"], - "client_id": "string", - "client_secret": "string", - "enterprise_base_url": "string" - } - }, - "oidc": { - "allow_signups": true, - "auth_url_params": {}, - "client_cert_file": "string", - "client_id": "string", - "client_key_file": "string", - "client_secret": "string", - "email_domain": ["string"], - "email_field": "string", - "group_allow_list": ["string"], - "group_auto_create": true, - "group_mapping": {}, - "group_regex_filter": {}, - "groups_field": "string", - "icon_url": { - "forceQuery": true, - "fragment": "string", - "host": "string", - "omitHost": true, - "opaque": "string", - "path": "string", - "rawFragment": "string", - "rawPath": "string", - "rawQuery": "string", - "scheme": "string", - "user": {} - }, - "ignore_email_verified": true, - "ignore_user_info": true, - "issuer_url": "string", - "name_field": "string", - "scopes": ["string"], - "sign_in_text": "string", - "signups_disabled_text": "string", - "skip_issuer_checks": true, - "user_role_field": "string", - "user_role_mapping": {}, - "user_roles_default": ["string"], - "username_field": "string" - }, - "pg_auth": "string", - "pg_connection_url": "string", - "pprof": { - "address": { - "host": "string", - "port": "string" - }, - "enable": true - }, - "prometheus": { - "address": { - "host": "string", - "port": "string" - }, - "aggregate_agent_stats_by": ["string"], - "collect_agent_stats": true, - "collect_db_metrics": true, - "enable": true - }, - "provisioner": { - "daemon_poll_interval": 0, - "daemon_poll_jitter": 0, - "daemon_psk": "string", - "daemon_types": ["string"], - "daemons": 0, - "force_cancel_interval": 0 - }, - "proxy_health_status_interval": 0, - "proxy_trusted_headers": ["string"], - "proxy_trusted_origins": ["string"], - "rate_limit": { - "api": 0, - "disable_all": true - }, - "redirect_to_access_url": true, - "scim_api_key": "string", - "secure_auth_cookie": true, - "session_lifetime": { - "default_duration": 0, - "disable_expiry_refresh": true, - "max_token_lifetime": 0 - }, - "ssh_keygen_algorithm": "string", - "strict_transport_security": 0, - "strict_transport_security_options": ["string"], - "support": { - "links": { - "value": [ - { - "icon": "bug", - "name": "string", - "target": "string" - } - ] - } - }, - "swagger": { - "enable": true - }, - "telemetry": { - "enable": true, - "trace": true, - "url": { - "forceQuery": true, - "fragment": "string", - "host": "string", - "omitHost": true, - "opaque": "string", - "path": "string", - "rawFragment": "string", - "rawPath": "string", - "rawQuery": "string", - "scheme": "string", - "user": {} - } - }, - "terms_of_service_url": "string", - "tls": { - "address": { - "host": "string", - "port": "string" - }, - "allow_insecure_ciphers": true, - "cert_file": ["string"], - "client_auth": "string", - "client_ca_file": "string", - "client_cert_file": "string", - "client_key_file": "string", - "enable": true, - "key_file": ["string"], - "min_version": "string", - "redirect_http": true, - "supported_ciphers": ["string"] - }, - "trace": { - "capture_logs": true, - "data_dog": true, - "enable": true, - "honeycomb_api_key": "string" - }, - "update_check": true, - "user_quiet_hours_schedule": { - "allow_user_custom": true, - "default_schedule": "string" - }, - "verbose": true, - "web_terminal_renderer": "string", - "wgtunnel_host": "string", - "wildcard_access_url": "string", - "write_config": true - }, - "options": [ - { - "annotations": { - "property1": "string", - "property2": "string" - }, - "default": "string", - "description": "string", - "env": "string", - "flag": "string", - "flag_shorthand": "string", - "group": { - "description": "string", - "name": "string", - "parent": { - "description": "string", - "name": "string", - "parent": {}, - "yaml": "string" - }, - "yaml": "string" - }, - "hidden": true, - "name": "string", - "required": true, - "use_instead": [{}], - "value": null, - "value_source": "", - "yaml": "string" - } - ] + "config": { + "access_url": { + "forceQuery": true, + "fragment": "string", + "host": "string", + "omitHost": true, + "opaque": "string", + "path": "string", + "rawFragment": "string", + "rawPath": "string", + "rawQuery": "string", + "scheme": "string", + "user": {} + }, + "address": { + "host": "string", + "port": "string" + }, + "agent_fallback_troubleshooting_url": { + "forceQuery": true, + "fragment": "string", + "host": "string", + "omitHost": true, + "opaque": "string", + "path": "string", + "rawFragment": "string", + "rawPath": "string", + "rawQuery": "string", + "scheme": "string", + "user": {} + }, + "agent_stat_refresh_interval": 0, + "allow_workspace_renames": true, + "autobuild_poll_interval": 0, + "browser_only": true, + "cache_directory": "string", + "cli_upgrade_message": "string", + "config": "string", + "config_ssh": { + "deploymentName": "string", + "sshconfigOptions": ["string"] + }, + "dangerous": { + "allow_all_cors": true, + "allow_path_app_sharing": true, + "allow_path_app_site_owner_access": true + }, + "derp": { + "config": { + "block_direct": true, + "force_websockets": true, + "path": "string", + "url": "string" + }, + "server": { + "enable": true, + "region_code": "string", + "region_id": 0, + "region_name": "string", + "relay_url": { + "forceQuery": true, + "fragment": "string", + "host": "string", + "omitHost": true, + "opaque": "string", + "path": "string", + "rawFragment": "string", + "rawPath": "string", + "rawQuery": "string", + "scheme": "string", + "user": {} + }, + "stun_addresses": ["string"] + } + }, + "disable_owner_workspace_exec": true, + "disable_password_auth": true, + "disable_path_apps": true, + "docs_url": { + "forceQuery": true, + "fragment": "string", + "host": "string", + "omitHost": true, + "opaque": "string", + "path": "string", + "rawFragment": "string", + "rawPath": "string", + "rawQuery": "string", + "scheme": "string", + "user": {} + }, + "enable_terraform_debug_mode": true, + "experiments": ["string"], + "external_auth": { + "value": [ + { + "app_install_url": "string", + "app_installations_url": "string", + "auth_url": "string", + "client_id": "string", + "device_code_url": "string", + "device_flow": true, + "display_icon": "string", + "display_name": "string", + "id": "string", + "no_refresh": true, + "regex": "string", + "scopes": ["string"], + "token_url": "string", + "type": "string", + "validate_url": "string" + } + ] + }, + "external_token_encryption_keys": ["string"], + "healthcheck": { + "refresh": 0, + "threshold_database": 0 + }, + "http_address": "string", + "in_memory_database": true, + "job_hang_detector_interval": 0, + "logging": { + "human": "string", + "json": "string", + "log_filter": ["string"], + "stackdriver": "string" + }, + "metrics_cache_refresh_interval": 0, + "notifications": { + "dispatch_timeout": 0, + "email": { + "auth": { + "identity": "string", + "password": "string", + "password_file": "string", + "username": "string" + }, + "force_tls": true, + "from": "string", + "hello": "string", + "smarthost": { + "host": "string", + "port": "string" + }, + "tls": { + "ca_file": "string", + "cert_file": "string", + "insecure_skip_verify": true, + "key_file": "string", + "server_name": "string", + "start_tls": true + } + }, + "fetch_interval": 0, + "lease_count": 0, + "lease_period": 0, + "max_send_attempts": 0, + "method": "string", + "retry_interval": 0, + "sync_buffer_size": 0, + "sync_interval": 0, + "webhook": { + "endpoint": { + "forceQuery": true, + "fragment": "string", + "host": "string", + "omitHost": true, + "opaque": "string", + "path": "string", + "rawFragment": "string", + "rawPath": "string", + "rawQuery": "string", + "scheme": "string", + "user": {} + } + } + }, + "oauth2": { + "github": { + "allow_everyone": true, + "allow_signups": true, + "allowed_orgs": ["string"], + "allowed_teams": ["string"], + "client_id": "string", + "client_secret": "string", + "enterprise_base_url": "string" + } + }, + "oidc": { + "allow_signups": true, + "auth_url_params": {}, + "client_cert_file": "string", + "client_id": "string", + "client_key_file": "string", + "client_secret": "string", + "email_domain": ["string"], + "email_field": "string", + "group_allow_list": ["string"], + "group_auto_create": true, + "group_mapping": {}, + "group_regex_filter": {}, + "groups_field": "string", + "icon_url": { + "forceQuery": true, + "fragment": "string", + "host": "string", + "omitHost": true, + "opaque": "string", + "path": "string", + "rawFragment": "string", + "rawPath": "string", + "rawQuery": "string", + "scheme": "string", + "user": {} + }, + "ignore_email_verified": true, + "ignore_user_info": true, + "issuer_url": "string", + "name_field": "string", + "scopes": ["string"], + "sign_in_text": "string", + "signups_disabled_text": "string", + "skip_issuer_checks": true, + "user_role_field": "string", + "user_role_mapping": {}, + "user_roles_default": ["string"], + "username_field": "string" + }, + "pg_auth": "string", + "pg_connection_url": "string", + "pprof": { + "address": { + "host": "string", + "port": "string" + }, + "enable": true + }, + "prometheus": { + "address": { + "host": "string", + "port": "string" + }, + "aggregate_agent_stats_by": ["string"], + "collect_agent_stats": true, + "collect_db_metrics": true, + "enable": true + }, + "provisioner": { + "daemon_poll_interval": 0, + "daemon_poll_jitter": 0, + "daemon_psk": "string", + "daemon_types": ["string"], + "daemons": 0, + "force_cancel_interval": 0 + }, + "proxy_health_status_interval": 0, + "proxy_trusted_headers": ["string"], + "proxy_trusted_origins": ["string"], + "rate_limit": { + "api": 0, + "disable_all": true + }, + "redirect_to_access_url": true, + "scim_api_key": "string", + "secure_auth_cookie": true, + "session_lifetime": { + "default_duration": 0, + "disable_expiry_refresh": true, + "max_token_lifetime": 0 + }, + "ssh_keygen_algorithm": "string", + "strict_transport_security": 0, + "strict_transport_security_options": ["string"], + "support": { + "links": { + "value": [ + { + "icon": "bug", + "name": "string", + "target": "string" + } + ] + } + }, + "swagger": { + "enable": true + }, + "telemetry": { + "enable": true, + "trace": true, + "url": { + "forceQuery": true, + "fragment": "string", + "host": "string", + "omitHost": true, + "opaque": "string", + "path": "string", + "rawFragment": "string", + "rawPath": "string", + "rawQuery": "string", + "scheme": "string", + "user": {} + } + }, + "terms_of_service_url": "string", + "tls": { + "address": { + "host": "string", + "port": "string" + }, + "allow_insecure_ciphers": true, + "cert_file": ["string"], + "client_auth": "string", + "client_ca_file": "string", + "client_cert_file": "string", + "client_key_file": "string", + "enable": true, + "key_file": ["string"], + "min_version": "string", + "redirect_http": true, + "supported_ciphers": ["string"] + }, + "trace": { + "capture_logs": true, + "data_dog": true, + "enable": true, + "honeycomb_api_key": "string" + }, + "update_check": true, + "user_quiet_hours_schedule": { + "allow_user_custom": true, + "default_schedule": "string" + }, + "verbose": true, + "web_terminal_renderer": "string", + "wgtunnel_host": "string", + "wildcard_access_url": "string", + "write_config": true + }, + "options": [ + { + "annotations": { + "property1": "string", + "property2": "string" + }, + "default": "string", + "description": "string", + "env": "string", + "flag": "string", + "flag_shorthand": "string", + "group": { + "description": "string", + "name": "string", + "parent": { + "description": "string", + "name": "string", + "parent": {}, + "yaml": "string" + }, + "yaml": "string" + }, + "hidden": true, + "name": "string", + "required": true, + "use_instead": [{}], + "value": null, + "value_source": "", + "yaml": "string" + } + ] } ``` @@ -2012,28 +2012,28 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "aggregated_from": "2019-08-24T14:15:22Z", - "collected_at": "2019-08-24T14:15:22Z", - "next_update_at": "2019-08-24T14:15:22Z", - "session_count": { - "jetbrains": 0, - "reconnecting_pty": 0, - "ssh": 0, - "vscode": 0 - }, - "workspaces": { - "building": 0, - "connection_latency_ms": { - "p50": 0, - "p95": 0 - }, - "failed": 0, - "pending": 0, - "running": 0, - "rx_bytes": 0, - "stopped": 0, - "tx_bytes": 0 - } + "aggregated_from": "2019-08-24T14:15:22Z", + "collected_at": "2019-08-24T14:15:22Z", + "next_update_at": "2019-08-24T14:15:22Z", + "session_count": { + "jetbrains": 0, + "reconnecting_pty": 0, + "ssh": 0, + "vscode": 0 + }, + "workspaces": { + "building": 0, + "connection_latency_ms": { + "p50": 0, + "p95": 0 + }, + "failed": 0, + "pending": 0, + "running": 0, + "rx_bytes": 0, + "stopped": 0, + "tx_bytes": 0 + } } ``` @@ -2051,344 +2051,344 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "access_url": { - "forceQuery": true, - "fragment": "string", - "host": "string", - "omitHost": true, - "opaque": "string", - "path": "string", - "rawFragment": "string", - "rawPath": "string", - "rawQuery": "string", - "scheme": "string", - "user": {} - }, - "address": { - "host": "string", - "port": "string" - }, - "agent_fallback_troubleshooting_url": { - "forceQuery": true, - "fragment": "string", - "host": "string", - "omitHost": true, - "opaque": "string", - "path": "string", - "rawFragment": "string", - "rawPath": "string", - "rawQuery": "string", - "scheme": "string", - "user": {} - }, - "agent_stat_refresh_interval": 0, - "allow_workspace_renames": true, - "autobuild_poll_interval": 0, - "browser_only": true, - "cache_directory": "string", - "cli_upgrade_message": "string", - "config": "string", - "config_ssh": { - "deploymentName": "string", - "sshconfigOptions": ["string"] - }, - "dangerous": { - "allow_all_cors": true, - "allow_path_app_sharing": true, - "allow_path_app_site_owner_access": true - }, - "derp": { - "config": { - "block_direct": true, - "force_websockets": true, - "path": "string", - "url": "string" - }, - "server": { - "enable": true, - "region_code": "string", - "region_id": 0, - "region_name": "string", - "relay_url": { - "forceQuery": true, - "fragment": "string", - "host": "string", - "omitHost": true, - "opaque": "string", - "path": "string", - "rawFragment": "string", - "rawPath": "string", - "rawQuery": "string", - "scheme": "string", - "user": {} - }, - "stun_addresses": ["string"] - } - }, - "disable_owner_workspace_exec": true, - "disable_password_auth": true, - "disable_path_apps": true, - "docs_url": { - "forceQuery": true, - "fragment": "string", - "host": "string", - "omitHost": true, - "opaque": "string", - "path": "string", - "rawFragment": "string", - "rawPath": "string", - "rawQuery": "string", - "scheme": "string", - "user": {} - }, - "enable_terraform_debug_mode": true, - "experiments": ["string"], - "external_auth": { - "value": [ - { - "app_install_url": "string", - "app_installations_url": "string", - "auth_url": "string", - "client_id": "string", - "device_code_url": "string", - "device_flow": true, - "display_icon": "string", - "display_name": "string", - "id": "string", - "no_refresh": true, - "regex": "string", - "scopes": ["string"], - "token_url": "string", - "type": "string", - "validate_url": "string" - } - ] - }, - "external_token_encryption_keys": ["string"], - "healthcheck": { - "refresh": 0, - "threshold_database": 0 - }, - "http_address": "string", - "in_memory_database": true, - "job_hang_detector_interval": 0, - "logging": { - "human": "string", - "json": "string", - "log_filter": ["string"], - "stackdriver": "string" - }, - "metrics_cache_refresh_interval": 0, - "notifications": { - "dispatch_timeout": 0, - "email": { - "auth": { - "identity": "string", - "password": "string", - "password_file": "string", - "username": "string" - }, - "force_tls": true, - "from": "string", - "hello": "string", - "smarthost": { - "host": "string", - "port": "string" - }, - "tls": { - "ca_file": "string", - "cert_file": "string", - "insecure_skip_verify": true, - "key_file": "string", - "server_name": "string", - "start_tls": true - } - }, - "fetch_interval": 0, - "lease_count": 0, - "lease_period": 0, - "max_send_attempts": 0, - "method": "string", - "retry_interval": 0, - "sync_buffer_size": 0, - "sync_interval": 0, - "webhook": { - "endpoint": { - "forceQuery": true, - "fragment": "string", - "host": "string", - "omitHost": true, - "opaque": "string", - "path": "string", - "rawFragment": "string", - "rawPath": "string", - "rawQuery": "string", - "scheme": "string", - "user": {} - } - } - }, - "oauth2": { - "github": { - "allow_everyone": true, - "allow_signups": true, - "allowed_orgs": ["string"], - "allowed_teams": ["string"], - "client_id": "string", - "client_secret": "string", - "enterprise_base_url": "string" - } - }, - "oidc": { - "allow_signups": true, - "auth_url_params": {}, - "client_cert_file": "string", - "client_id": "string", - "client_key_file": "string", - "client_secret": "string", - "email_domain": ["string"], - "email_field": "string", - "group_allow_list": ["string"], - "group_auto_create": true, - "group_mapping": {}, - "group_regex_filter": {}, - "groups_field": "string", - "icon_url": { - "forceQuery": true, - "fragment": "string", - "host": "string", - "omitHost": true, - "opaque": "string", - "path": "string", - "rawFragment": "string", - "rawPath": "string", - "rawQuery": "string", - "scheme": "string", - "user": {} - }, - "ignore_email_verified": true, - "ignore_user_info": true, - "issuer_url": "string", - "name_field": "string", - "scopes": ["string"], - "sign_in_text": "string", - "signups_disabled_text": "string", - "skip_issuer_checks": true, - "user_role_field": "string", - "user_role_mapping": {}, - "user_roles_default": ["string"], - "username_field": "string" - }, - "pg_auth": "string", - "pg_connection_url": "string", - "pprof": { - "address": { - "host": "string", - "port": "string" - }, - "enable": true - }, - "prometheus": { - "address": { - "host": "string", - "port": "string" - }, - "aggregate_agent_stats_by": ["string"], - "collect_agent_stats": true, - "collect_db_metrics": true, - "enable": true - }, - "provisioner": { - "daemon_poll_interval": 0, - "daemon_poll_jitter": 0, - "daemon_psk": "string", - "daemon_types": ["string"], - "daemons": 0, - "force_cancel_interval": 0 - }, - "proxy_health_status_interval": 0, - "proxy_trusted_headers": ["string"], - "proxy_trusted_origins": ["string"], - "rate_limit": { - "api": 0, - "disable_all": true - }, - "redirect_to_access_url": true, - "scim_api_key": "string", - "secure_auth_cookie": true, - "session_lifetime": { - "default_duration": 0, - "disable_expiry_refresh": true, - "max_token_lifetime": 0 - }, - "ssh_keygen_algorithm": "string", - "strict_transport_security": 0, - "strict_transport_security_options": ["string"], - "support": { - "links": { - "value": [ - { - "icon": "bug", - "name": "string", - "target": "string" - } - ] - } - }, - "swagger": { - "enable": true - }, - "telemetry": { - "enable": true, - "trace": true, - "url": { - "forceQuery": true, - "fragment": "string", - "host": "string", - "omitHost": true, - "opaque": "string", - "path": "string", - "rawFragment": "string", - "rawPath": "string", - "rawQuery": "string", - "scheme": "string", - "user": {} - } - }, - "terms_of_service_url": "string", - "tls": { - "address": { - "host": "string", - "port": "string" - }, - "allow_insecure_ciphers": true, - "cert_file": ["string"], - "client_auth": "string", - "client_ca_file": "string", - "client_cert_file": "string", - "client_key_file": "string", - "enable": true, - "key_file": ["string"], - "min_version": "string", - "redirect_http": true, - "supported_ciphers": ["string"] - }, - "trace": { - "capture_logs": true, - "data_dog": true, - "enable": true, - "honeycomb_api_key": "string" - }, - "update_check": true, - "user_quiet_hours_schedule": { - "allow_user_custom": true, - "default_schedule": "string" - }, - "verbose": true, - "web_terminal_renderer": "string", - "wgtunnel_host": "string", - "wildcard_access_url": "string", - "write_config": true + "access_url": { + "forceQuery": true, + "fragment": "string", + "host": "string", + "omitHost": true, + "opaque": "string", + "path": "string", + "rawFragment": "string", + "rawPath": "string", + "rawQuery": "string", + "scheme": "string", + "user": {} + }, + "address": { + "host": "string", + "port": "string" + }, + "agent_fallback_troubleshooting_url": { + "forceQuery": true, + "fragment": "string", + "host": "string", + "omitHost": true, + "opaque": "string", + "path": "string", + "rawFragment": "string", + "rawPath": "string", + "rawQuery": "string", + "scheme": "string", + "user": {} + }, + "agent_stat_refresh_interval": 0, + "allow_workspace_renames": true, + "autobuild_poll_interval": 0, + "browser_only": true, + "cache_directory": "string", + "cli_upgrade_message": "string", + "config": "string", + "config_ssh": { + "deploymentName": "string", + "sshconfigOptions": ["string"] + }, + "dangerous": { + "allow_all_cors": true, + "allow_path_app_sharing": true, + "allow_path_app_site_owner_access": true + }, + "derp": { + "config": { + "block_direct": true, + "force_websockets": true, + "path": "string", + "url": "string" + }, + "server": { + "enable": true, + "region_code": "string", + "region_id": 0, + "region_name": "string", + "relay_url": { + "forceQuery": true, + "fragment": "string", + "host": "string", + "omitHost": true, + "opaque": "string", + "path": "string", + "rawFragment": "string", + "rawPath": "string", + "rawQuery": "string", + "scheme": "string", + "user": {} + }, + "stun_addresses": ["string"] + } + }, + "disable_owner_workspace_exec": true, + "disable_password_auth": true, + "disable_path_apps": true, + "docs_url": { + "forceQuery": true, + "fragment": "string", + "host": "string", + "omitHost": true, + "opaque": "string", + "path": "string", + "rawFragment": "string", + "rawPath": "string", + "rawQuery": "string", + "scheme": "string", + "user": {} + }, + "enable_terraform_debug_mode": true, + "experiments": ["string"], + "external_auth": { + "value": [ + { + "app_install_url": "string", + "app_installations_url": "string", + "auth_url": "string", + "client_id": "string", + "device_code_url": "string", + "device_flow": true, + "display_icon": "string", + "display_name": "string", + "id": "string", + "no_refresh": true, + "regex": "string", + "scopes": ["string"], + "token_url": "string", + "type": "string", + "validate_url": "string" + } + ] + }, + "external_token_encryption_keys": ["string"], + "healthcheck": { + "refresh": 0, + "threshold_database": 0 + }, + "http_address": "string", + "in_memory_database": true, + "job_hang_detector_interval": 0, + "logging": { + "human": "string", + "json": "string", + "log_filter": ["string"], + "stackdriver": "string" + }, + "metrics_cache_refresh_interval": 0, + "notifications": { + "dispatch_timeout": 0, + "email": { + "auth": { + "identity": "string", + "password": "string", + "password_file": "string", + "username": "string" + }, + "force_tls": true, + "from": "string", + "hello": "string", + "smarthost": { + "host": "string", + "port": "string" + }, + "tls": { + "ca_file": "string", + "cert_file": "string", + "insecure_skip_verify": true, + "key_file": "string", + "server_name": "string", + "start_tls": true + } + }, + "fetch_interval": 0, + "lease_count": 0, + "lease_period": 0, + "max_send_attempts": 0, + "method": "string", + "retry_interval": 0, + "sync_buffer_size": 0, + "sync_interval": 0, + "webhook": { + "endpoint": { + "forceQuery": true, + "fragment": "string", + "host": "string", + "omitHost": true, + "opaque": "string", + "path": "string", + "rawFragment": "string", + "rawPath": "string", + "rawQuery": "string", + "scheme": "string", + "user": {} + } + } + }, + "oauth2": { + "github": { + "allow_everyone": true, + "allow_signups": true, + "allowed_orgs": ["string"], + "allowed_teams": ["string"], + "client_id": "string", + "client_secret": "string", + "enterprise_base_url": "string" + } + }, + "oidc": { + "allow_signups": true, + "auth_url_params": {}, + "client_cert_file": "string", + "client_id": "string", + "client_key_file": "string", + "client_secret": "string", + "email_domain": ["string"], + "email_field": "string", + "group_allow_list": ["string"], + "group_auto_create": true, + "group_mapping": {}, + "group_regex_filter": {}, + "groups_field": "string", + "icon_url": { + "forceQuery": true, + "fragment": "string", + "host": "string", + "omitHost": true, + "opaque": "string", + "path": "string", + "rawFragment": "string", + "rawPath": "string", + "rawQuery": "string", + "scheme": "string", + "user": {} + }, + "ignore_email_verified": true, + "ignore_user_info": true, + "issuer_url": "string", + "name_field": "string", + "scopes": ["string"], + "sign_in_text": "string", + "signups_disabled_text": "string", + "skip_issuer_checks": true, + "user_role_field": "string", + "user_role_mapping": {}, + "user_roles_default": ["string"], + "username_field": "string" + }, + "pg_auth": "string", + "pg_connection_url": "string", + "pprof": { + "address": { + "host": "string", + "port": "string" + }, + "enable": true + }, + "prometheus": { + "address": { + "host": "string", + "port": "string" + }, + "aggregate_agent_stats_by": ["string"], + "collect_agent_stats": true, + "collect_db_metrics": true, + "enable": true + }, + "provisioner": { + "daemon_poll_interval": 0, + "daemon_poll_jitter": 0, + "daemon_psk": "string", + "daemon_types": ["string"], + "daemons": 0, + "force_cancel_interval": 0 + }, + "proxy_health_status_interval": 0, + "proxy_trusted_headers": ["string"], + "proxy_trusted_origins": ["string"], + "rate_limit": { + "api": 0, + "disable_all": true + }, + "redirect_to_access_url": true, + "scim_api_key": "string", + "secure_auth_cookie": true, + "session_lifetime": { + "default_duration": 0, + "disable_expiry_refresh": true, + "max_token_lifetime": 0 + }, + "ssh_keygen_algorithm": "string", + "strict_transport_security": 0, + "strict_transport_security_options": ["string"], + "support": { + "links": { + "value": [ + { + "icon": "bug", + "name": "string", + "target": "string" + } + ] + } + }, + "swagger": { + "enable": true + }, + "telemetry": { + "enable": true, + "trace": true, + "url": { + "forceQuery": true, + "fragment": "string", + "host": "string", + "omitHost": true, + "opaque": "string", + "path": "string", + "rawFragment": "string", + "rawPath": "string", + "rawQuery": "string", + "scheme": "string", + "user": {} + } + }, + "terms_of_service_url": "string", + "tls": { + "address": { + "host": "string", + "port": "string" + }, + "allow_insecure_ciphers": true, + "cert_file": ["string"], + "client_auth": "string", + "client_ca_file": "string", + "client_cert_file": "string", + "client_key_file": "string", + "enable": true, + "key_file": ["string"], + "min_version": "string", + "redirect_http": true, + "supported_ciphers": ["string"] + }, + "trace": { + "capture_logs": true, + "data_dog": true, + "enable": true, + "honeycomb_api_key": "string" + }, + "update_check": true, + "user_quiet_hours_schedule": { + "allow_user_custom": true, + "default_schedule": "string" + }, + "verbose": true, + "web_terminal_renderer": "string", + "wgtunnel_host": "string", + "wildcard_access_url": "string", + "write_config": true } ``` @@ -2494,26 +2494,26 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "errors": ["string"], - "features": { - "property1": { - "actual": 0, - "enabled": true, - "entitlement": "entitled", - "limit": 0 - }, - "property2": { - "actual": 0, - "enabled": true, - "entitlement": "entitled", - "limit": 0 - } - }, - "has_license": true, - "refreshed_at": "2019-08-24T14:15:22Z", - "require_telemetry": true, - "trial": true, - "warnings": ["string"] + "errors": ["string"], + "features": { + "property1": { + "actual": 0, + "enabled": true, + "entitlement": "entitled", + "limit": 0 + }, + "property2": { + "actual": 0, + "enabled": true, + "entitlement": "entitled", + "limit": 0 + } + }, + "has_license": true, + "refreshed_at": "2019-08-24T14:15:22Z", + "require_telemetry": true, + "trial": true, + "warnings": ["string"] } ``` @@ -2553,31 +2553,31 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "app_install_url": "string", - "app_installable": true, - "authenticated": true, - "device": true, - "display_name": "string", - "installations": [ - { - "account": { - "avatar_url": "string", - "id": 0, - "login": "string", - "name": "string", - "profile_url": "string" - }, - "configure_url": "string", - "id": 0 - } - ], - "user": { - "avatar_url": "string", - "id": 0, - "login": "string", - "name": "string", - "profile_url": "string" - } + "app_install_url": "string", + "app_installable": true, + "authenticated": true, + "device": true, + "display_name": "string", + "installations": [ + { + "account": { + "avatar_url": "string", + "id": 0, + "login": "string", + "name": "string", + "profile_url": "string" + }, + "configure_url": "string", + "id": 0 + } + ], + "user": { + "avatar_url": "string", + "id": 0, + "login": "string", + "name": "string", + "profile_url": "string" + } } ``` @@ -2597,15 +2597,15 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "account": { - "avatar_url": "string", - "id": 0, - "login": "string", - "name": "string", - "profile_url": "string" - }, - "configure_url": "string", - "id": 0 + "account": { + "avatar_url": "string", + "id": 0, + "login": "string", + "name": "string", + "profile_url": "string" + }, + "configure_url": "string", + "id": 0 } ``` @@ -2621,21 +2621,21 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "app_install_url": "string", - "app_installations_url": "string", - "auth_url": "string", - "client_id": "string", - "device_code_url": "string", - "device_flow": true, - "display_icon": "string", - "display_name": "string", - "id": "string", - "no_refresh": true, - "regex": "string", - "scopes": ["string"], - "token_url": "string", - "type": "string", - "validate_url": "string" + "app_install_url": "string", + "app_installations_url": "string", + "auth_url": "string", + "client_id": "string", + "device_code_url": "string", + "device_flow": true, + "display_icon": "string", + "display_name": "string", + "id": "string", + "no_refresh": true, + "regex": "string", + "scopes": ["string"], + "token_url": "string", + "type": "string", + "validate_url": "string" } ``` @@ -2664,11 +2664,11 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "device_code": "string", - "expires_in": 0, - "interval": 0, - "user_code": "string", - "verification_uri": "string" + "device_code": "string", + "expires_in": 0, + "interval": 0, + "user_code": "string", + "verification_uri": "string" } ``` @@ -2686,13 +2686,13 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "authenticated": true, - "created_at": "2019-08-24T14:15:22Z", - "expires": "2019-08-24T14:15:22Z", - "has_refresh_token": true, - "provider_id": "string", - "updated_at": "2019-08-24T14:15:22Z", - "validate_error": "string" + "authenticated": true, + "created_at": "2019-08-24T14:15:22Z", + "expires": "2019-08-24T14:15:22Z", + "has_refresh_token": true, + "provider_id": "string", + "updated_at": "2019-08-24T14:15:22Z", + "validate_error": "string" } ``` @@ -2712,11 +2712,11 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "avatar_url": "string", - "id": 0, - "login": "string", - "name": "string", - "profile_url": "string" + "avatar_url": "string", + "id": 0, + "login": "string", + "name": "string", + "profile_url": "string" } ``` @@ -2734,10 +2734,10 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "actual": 0, - "enabled": true, - "entitlement": "entitled", - "limit": 0 + "actual": 0, + "enabled": true, + "entitlement": "entitled", + "limit": 0 } ``` @@ -2754,7 +2754,7 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "key": "string" + "key": "string" } ``` @@ -2768,30 +2768,30 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```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", - "login_type": "", - "name": "string", - "organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "roles": [ - { - "display_name": "string", - "name": "string", - "organization_id": "string" - } - ], - "status": "active", - "theme_preference": "string", - "updated_at": "2019-08-24T14:15:22Z", - "username": "string" - } - ] + "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", + "login_type": "", + "name": "string", + "organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "roles": [ + { + "display_name": "string", + "name": "string", + "organization_id": "string" + } + ], + "status": "active", + "theme_preference": "string", + "updated_at": "2019-08-24T14:15:22Z", + "username": "string" + } + ] } ``` @@ -2806,10 +2806,10 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```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" + "created_at": "2019-08-24T14:15:22Z", + "public_key": "string", + "updated_at": "2019-08-24T14:15:22Z", + "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5" } ``` @@ -2826,29 +2826,29 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "avatar_url": "string", - "display_name": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "members": [ - { - "avatar_url": "http://example.com", - "created_at": "2019-08-24T14:15:22Z", - "email": "user@example.com", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "last_seen_at": "2019-08-24T14:15:22Z", - "login_type": "", - "name": "string", - "status": "active", - "theme_preference": "string", - "updated_at": "2019-08-24T14:15:22Z", - "username": "string" - } - ], - "name": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "quota_allowance": 0, - "source": "user", - "total_member_count": 0 + "avatar_url": "string", + "display_name": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "members": [ + { + "avatar_url": "http://example.com", + "created_at": "2019-08-24T14:15:22Z", + "email": "user@example.com", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "last_seen_at": "2019-08-24T14:15:22Z", + "login_type": "", + "name": "string", + "status": "active", + "theme_preference": "string", + "updated_at": "2019-08-24T14:15:22Z", + "username": "string" + } + ], + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "quota_allowance": 0, + "source": "user", + "total_member_count": 0 } ``` @@ -2885,9 +2885,9 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "interval": 0, - "threshold": 0, - "url": "string" + "interval": 0, + "threshold": 0, + "url": "string" } ``` @@ -2903,8 +2903,8 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "refresh": 0, - "threshold_database": 0 + "refresh": 0, + "threshold_database": 0 } ``` @@ -2934,8 +2934,8 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "agentID": "bc282582-04f9-45ce-b904-3e3bfab66958", - "url": "string" + "agentID": "bc282582-04f9-45ce-b904-3e3bfab66958", + "url": "string" } ``` @@ -2950,7 +2950,7 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "signed_token": "string" + "signed_token": "string" } ``` @@ -2964,12 +2964,12 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978", - "critical": 0, - "high": 0, - "medium": 0, - "results_url": "string", - "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9" + "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978", + "critical": 0, + "high": 0, + "medium": 0, + "results_url": "string", + "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9" } ``` @@ -3002,10 +3002,10 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "claims": {}, - "id": 0, - "uploaded_at": "2019-08-24T14:15:22Z", - "uuid": "095be615-a8ad-4c33-8e9c-c7612fbf6c9f" + "claims": {}, + "id": 0, + "uploaded_at": "2019-08-24T14:15:22Z", + "uuid": "095be615-a8ad-4c33-8e9c-c7612fbf6c9f" } ``` @@ -3022,9 +3022,9 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "icon": "bug", - "name": "string", - "target": "string" + "icon": "bug", + "name": "string", + "target": "string" } ``` @@ -3081,10 +3081,10 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "human": "string", - "json": "string", - "log_filter": ["string"], - "stackdriver": "string" + "human": "string", + "json": "string", + "log_filter": ["string"], + "stackdriver": "string" } ``` @@ -3120,8 +3120,8 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "email": "user@example.com", - "password": "string" + "email": "user@example.com", + "password": "string" } ``` @@ -3136,7 +3136,7 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "session_token": "string" + "session_token": "string" } ``` @@ -3150,10 +3150,10 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "display_name": "string", - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "name": "string" + "display_name": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "string" } ``` @@ -3170,9 +3170,9 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "avatar_url": "http://example.com", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "username": "string" + "avatar_url": "http://example.com", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "username": "string" } ``` @@ -3188,8 +3188,8 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "available": ["string"], - "default": "string" + "available": ["string"], + "default": "string" } ``` @@ -3204,9 +3204,9 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "disabled": true, - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "updated_at": "2019-08-24T14:15:22Z" + "disabled": true, + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "updated_at": "2019-08-24T14:15:22Z" } ``` @@ -3222,14 +3222,14 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "actions": "string", - "body_template": "string", - "group": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "kind": "string", - "method": "string", - "name": "string", - "title_template": "string" + "actions": "string", + "body_template": "string", + "group": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "kind": "string", + "method": "string", + "name": "string", + "title_template": "string" } ``` @@ -3250,53 +3250,53 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "dispatch_timeout": 0, - "email": { - "auth": { - "identity": "string", - "password": "string", - "password_file": "string", - "username": "string" - }, - "force_tls": true, - "from": "string", - "hello": "string", - "smarthost": { - "host": "string", - "port": "string" - }, - "tls": { - "ca_file": "string", - "cert_file": "string", - "insecure_skip_verify": true, - "key_file": "string", - "server_name": "string", - "start_tls": true - } - }, - "fetch_interval": 0, - "lease_count": 0, - "lease_period": 0, - "max_send_attempts": 0, - "method": "string", - "retry_interval": 0, - "sync_buffer_size": 0, - "sync_interval": 0, - "webhook": { - "endpoint": { - "forceQuery": true, - "fragment": "string", - "host": "string", - "omitHost": true, - "opaque": "string", - "path": "string", - "rawFragment": "string", - "rawPath": "string", - "rawQuery": "string", - "scheme": "string", - "user": {} - } - } + "dispatch_timeout": 0, + "email": { + "auth": { + "identity": "string", + "password": "string", + "password_file": "string", + "username": "string" + }, + "force_tls": true, + "from": "string", + "hello": "string", + "smarthost": { + "host": "string", + "port": "string" + }, + "tls": { + "ca_file": "string", + "cert_file": "string", + "insecure_skip_verify": true, + "key_file": "string", + "server_name": "string", + "start_tls": true + } + }, + "fetch_interval": 0, + "lease_count": 0, + "lease_period": 0, + "max_send_attempts": 0, + "method": "string", + "retry_interval": 0, + "sync_buffer_size": 0, + "sync_interval": 0, + "webhook": { + "endpoint": { + "forceQuery": true, + "fragment": "string", + "host": "string", + "omitHost": true, + "opaque": "string", + "path": "string", + "rawFragment": "string", + "rawPath": "string", + "rawQuery": "string", + "scheme": "string", + "user": {} + } + } } ``` @@ -3320,10 +3320,10 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "identity": "string", - "password": "string", - "password_file": "string", - "username": "string" + "identity": "string", + "password": "string", + "password_file": "string", + "username": "string" } ``` @@ -3340,27 +3340,27 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "auth": { - "identity": "string", - "password": "string", - "password_file": "string", - "username": "string" - }, - "force_tls": true, - "from": "string", - "hello": "string", - "smarthost": { - "host": "string", - "port": "string" - }, - "tls": { - "ca_file": "string", - "cert_file": "string", - "insecure_skip_verify": true, - "key_file": "string", - "server_name": "string", - "start_tls": true - } + "auth": { + "identity": "string", + "password": "string", + "password_file": "string", + "username": "string" + }, + "force_tls": true, + "from": "string", + "hello": "string", + "smarthost": { + "host": "string", + "port": "string" + }, + "tls": { + "ca_file": "string", + "cert_file": "string", + "insecure_skip_verify": true, + "key_file": "string", + "server_name": "string", + "start_tls": true + } } ``` @@ -3379,12 +3379,12 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "ca_file": "string", - "cert_file": "string", - "insecure_skip_verify": true, - "key_file": "string", - "server_name": "string", - "start_tls": true + "ca_file": "string", + "cert_file": "string", + "insecure_skip_verify": true, + "key_file": "string", + "server_name": "string", + "start_tls": true } ``` @@ -3403,7 +3403,7 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "notifier_paused": true + "notifier_paused": true } ``` @@ -3417,19 +3417,19 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "endpoint": { - "forceQuery": true, - "fragment": "string", - "host": "string", - "omitHost": true, - "opaque": "string", - "path": "string", - "rawFragment": "string", - "rawPath": "string", - "rawQuery": "string", - "scheme": "string", - "user": {} - } + "endpoint": { + "forceQuery": true, + "fragment": "string", + "host": "string", + "omitHost": true, + "opaque": "string", + "path": "string", + "rawFragment": "string", + "rawPath": "string", + "rawQuery": "string", + "scheme": "string", + "user": {} + } } ``` @@ -3443,9 +3443,9 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "authorization": "string", - "device_authorization": "string", - "token": "string" + "authorization": "string", + "device_authorization": "string", + "token": "string" } ``` @@ -3461,15 +3461,15 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "github": { - "allow_everyone": true, - "allow_signups": true, - "allowed_orgs": ["string"], - "allowed_teams": ["string"], - "client_id": "string", - "client_secret": "string", - "enterprise_base_url": "string" - } + "github": { + "allow_everyone": true, + "allow_signups": true, + "allowed_orgs": ["string"], + "allowed_teams": ["string"], + "client_id": "string", + "client_secret": "string", + "enterprise_base_url": "string" + } } ``` @@ -3483,13 +3483,13 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "allow_everyone": true, - "allow_signups": true, - "allowed_orgs": ["string"], - "allowed_teams": ["string"], - "client_id": "string", - "client_secret": "string", - "enterprise_base_url": "string" + "allow_everyone": true, + "allow_signups": true, + "allowed_orgs": ["string"], + "allowed_teams": ["string"], + "client_id": "string", + "client_secret": "string", + "enterprise_base_url": "string" } ``` @@ -3509,15 +3509,15 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "callback_url": "string", - "endpoints": { - "authorization": "string", - "device_authorization": "string", - "token": "string" - }, - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "name": "string" + "callback_url": "string", + "endpoints": { + "authorization": "string", + "device_authorization": "string", + "token": "string" + }, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "string" } ``` @@ -3535,9 +3535,9 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "client_secret_truncated": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "last_used_at": "string" + "client_secret_truncated": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "last_used_at": "string" } ``` @@ -3553,8 +3553,8 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "client_secret_full": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08" + "client_secret_full": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08" } ``` @@ -3569,10 +3569,10 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "expires_at": "2019-08-24T14:15:22Z", - "state_string": "string", - "to_type": "", - "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5" + "expires_at": "2019-08-24T14:15:22Z", + "state_string": "string", + "to_type": "", + "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5" } ``` @@ -3589,9 +3589,9 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "enabled": true, - "iconUrl": "string", - "signInText": "string" + "enabled": true, + "iconUrl": "string", + "signInText": "string" } ``` @@ -3607,44 +3607,44 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "allow_signups": true, - "auth_url_params": {}, - "client_cert_file": "string", - "client_id": "string", - "client_key_file": "string", - "client_secret": "string", - "email_domain": ["string"], - "email_field": "string", - "group_allow_list": ["string"], - "group_auto_create": true, - "group_mapping": {}, - "group_regex_filter": {}, - "groups_field": "string", - "icon_url": { - "forceQuery": true, - "fragment": "string", - "host": "string", - "omitHost": true, - "opaque": "string", - "path": "string", - "rawFragment": "string", - "rawPath": "string", - "rawQuery": "string", - "scheme": "string", - "user": {} - }, - "ignore_email_verified": true, - "ignore_user_info": true, - "issuer_url": "string", - "name_field": "string", - "scopes": ["string"], - "sign_in_text": "string", - "signups_disabled_text": "string", - "skip_issuer_checks": true, - "user_role_field": "string", - "user_role_mapping": {}, - "user_roles_default": ["string"], - "username_field": "string" + "allow_signups": true, + "auth_url_params": {}, + "client_cert_file": "string", + "client_id": "string", + "client_key_file": "string", + "client_secret": "string", + "email_domain": ["string"], + "email_field": "string", + "group_allow_list": ["string"], + "group_auto_create": true, + "group_mapping": {}, + "group_regex_filter": {}, + "groups_field": "string", + "icon_url": { + "forceQuery": true, + "fragment": "string", + "host": "string", + "omitHost": true, + "opaque": "string", + "path": "string", + "rawFragment": "string", + "rawPath": "string", + "rawQuery": "string", + "scheme": "string", + "user": {} + }, + "ignore_email_verified": true, + "ignore_user_info": true, + "issuer_url": "string", + "name_field": "string", + "scopes": ["string"], + "sign_in_text": "string", + "signups_disabled_text": "string", + "skip_issuer_checks": true, + "user_role_field": "string", + "user_role_mapping": {}, + "user_roles_default": ["string"], + "username_field": "string" } ``` @@ -3683,14 +3683,14 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "created_at": "2019-08-24T14:15:22Z", - "description": "string", - "display_name": "string", - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "is_default": true, - "name": "string", - "updated_at": "2019-08-24T14:15:22Z" + "created_at": "2019-08-24T14:15:22Z", + "description": "string", + "display_name": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "is_default": true, + "name": "string", + "updated_at": "2019-08-24T14:15:22Z" } ``` @@ -3711,17 +3711,17 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "created_at": "2019-08-24T14:15:22Z", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "roles": [ - { - "display_name": "string", - "name": "string", - "organization_id": "string" - } - ], - "updated_at": "2019-08-24T14:15:22Z", - "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5" + "created_at": "2019-08-24T14:15:22Z", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "roles": [ + { + "display_name": "string", + "name": "string", + "organization_id": "string" + } + ], + "updated_at": "2019-08-24T14:15:22Z", + "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5" } ``` @@ -3739,28 +3739,28 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "avatar_url": "string", - "created_at": "2019-08-24T14:15:22Z", - "email": "string", - "global_roles": [ - { - "display_name": "string", - "name": "string", - "organization_id": "string" - } - ], - "name": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "roles": [ - { - "display_name": "string", - "name": "string", - "organization_id": "string" - } - ], - "updated_at": "2019-08-24T14:15:22Z", - "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5", - "username": "string" + "avatar_url": "string", + "created_at": "2019-08-24T14:15:22Z", + "email": "string", + "global_roles": [ + { + "display_name": "string", + "name": "string", + "organization_id": "string" + } + ], + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "roles": [ + { + "display_name": "string", + "name": "string", + "organization_id": "string" + } + ], + "updated_at": "2019-08-24T14:15:22Z", + "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5", + "username": "string" } ``` @@ -3783,12 +3783,12 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "add_users": ["string"], - "avatar_url": "string", - "display_name": "string", - "name": "string", - "quota_allowance": 0, - "remove_users": ["string"] + "add_users": ["string"], + "avatar_url": "string", + "display_name": "string", + "name": "string", + "quota_allowance": 0, + "remove_users": ["string"] } ``` @@ -3807,8 +3807,8 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "message": "string", - "name": "string" + "message": "string", + "name": "string" } ``` @@ -3823,11 +3823,11 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "display_name": "string", - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "name": "string", - "regenerate_token": true + "display_name": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "string", + "regenerate_token": true } ``` @@ -3845,9 +3845,9 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "action": "application_connect", - "negate": true, - "resource_type": "*" + "action": "application_connect", + "negate": true, + "resource_type": "*" } ``` @@ -3863,9 +3863,9 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "callback_url": "string", - "icon": "string", - "name": "string" + "callback_url": "string", + "icon": "string", + "name": "string" } ``` @@ -3881,8 +3881,8 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978", - "app_name": "vscode" + "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978", + "app_name": "vscode" } ``` @@ -3897,11 +3897,11 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "address": { - "host": "string", - "port": "string" - }, - "enable": true + "address": { + "host": "string", + "port": "string" + }, + "enable": true } ``` @@ -3916,14 +3916,14 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "address": { - "host": "string", - "port": "string" - }, - "aggregate_agent_stats_by": ["string"], - "collect_agent_stats": true, - "collect_db_metrics": true, - "enable": true + "address": { + "host": "string", + "port": "string" + }, + "aggregate_agent_stats_by": ["string"], + "collect_agent_stats": true, + "collect_db_metrics": true, + "enable": true } ``` @@ -3941,12 +3941,12 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "daemon_poll_interval": 0, - "daemon_poll_jitter": 0, - "daemon_psk": "string", - "daemon_types": ["string"], - "daemons": 0, - "force_cancel_interval": 0 + "daemon_poll_interval": 0, + "daemon_poll_jitter": 0, + "daemon_psk": "string", + "daemon_types": ["string"], + "daemons": 0, + "force_cancel_interval": 0 } ``` @@ -3965,18 +3965,18 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "api_version": "string", - "created_at": "2019-08-24T14:15:22Z", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "last_seen_at": "2019-08-24T14:15:22Z", - "name": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "provisioners": ["string"], - "tags": { - "property1": "string", - "property2": "string" - }, - "version": "string" + "api_version": "string", + "created_at": "2019-08-24T14:15:22Z", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "last_seen_at": "2019-08-24T14:15:22Z", + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "provisioners": ["string"], + "tags": { + "property1": "string", + "property2": "string" + }, + "version": "string" } ``` @@ -3999,22 +3999,22 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "canceled_at": "2019-08-24T14:15:22Z", - "completed_at": "2019-08-24T14:15:22Z", - "created_at": "2019-08-24T14:15:22Z", - "error": "string", - "error_code": "REQUIRED_TEMPLATE_VARIABLES", - "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "queue_position": 0, - "queue_size": 0, - "started_at": "2019-08-24T14:15:22Z", - "status": "pending", - "tags": { - "property1": "string", - "property2": "string" - }, - "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" + "canceled_at": "2019-08-24T14:15:22Z", + "completed_at": "2019-08-24T14:15:22Z", + "created_at": "2019-08-24T14:15:22Z", + "error": "string", + "error_code": "REQUIRED_TEMPLATE_VARIABLES", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "queue_position": 0, + "queue_size": 0, + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" } ``` @@ -4053,12 +4053,12 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "created_at": "2019-08-24T14:15:22Z", - "id": 0, - "log_level": "trace", - "log_source": "provisioner_daemon", - "output": "string", - "stage": "string" + "created_at": "2019-08-24T14:15:22Z", + "id": 0, + "log_level": "trace", + "log_source": "provisioner_daemon", + "output": "string", + "stage": "string" } ``` @@ -4107,14 +4107,14 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "created_at": "2019-08-24T14:15:22Z", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "name": "string", - "organization": "452c1a86-a0af-475b-b03f-724878b0f387", - "tags": { - "property1": "string", - "property2": "string" - } + "created_at": "2019-08-24T14:15:22Z", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "string", + "organization": "452c1a86-a0af-475b-b03f-724878b0f387", + "tags": { + "property1": "string", + "property2": "string" + } } ``` @@ -4161,8 +4161,8 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "errors": ["string"], - "warnings": ["string"] + "errors": ["string"], + "warnings": ["string"] } ``` @@ -4194,7 +4194,7 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "deadline": "2019-08-24T14:15:22Z" + "deadline": "2019-08-24T14:15:22Z" } ``` @@ -4208,9 +4208,9 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "callback_url": "string", - "icon": "string", - "name": "string" + "callback_url": "string", + "icon": "string", + "name": "string" } ``` @@ -4294,8 +4294,8 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "api": 0, - "disable_all": true + "api": 0, + "disable_all": true } ``` @@ -4310,17 +4310,17 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```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", - "login_type": "", - "name": "string", - "status": "active", - "theme_preference": "string", - "updated_at": "2019-08-24T14:15:22Z", - "username": "string" + "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", + "login_type": "", + "name": "string", + "status": "active", + "theme_preference": "string", + "updated_at": "2019-08-24T14:15:22Z", + "username": "string" } ``` @@ -4351,13 +4351,13 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "display_name": "string", - "healthy": true, - "icon_url": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "name": "string", - "path_app_url": "string", - "wildcard_hostname": "string" + "display_name": "string", + "healthy": true, + "icon_url": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "string", + "path_app_url": "string", + "wildcard_hostname": "string" } ``` @@ -4377,17 +4377,17 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "regions": [ - { - "display_name": "string", - "healthy": true, - "icon_url": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "name": "string", - "path_app_url": "string", - "wildcard_hostname": "string" - } - ] + "regions": [ + { + "display_name": "string", + "healthy": true, + "icon_url": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "string", + "path_app_url": "string", + "wildcard_hostname": "string" + } + ] } ``` @@ -4401,31 +4401,31 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "regions": [ - { - "created_at": "2019-08-24T14:15:22Z", - "deleted": true, - "derp_enabled": true, - "derp_only": true, - "display_name": "string", - "healthy": true, - "icon_url": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "name": "string", - "path_app_url": "string", - "status": { - "checked_at": "2019-08-24T14:15:22Z", - "report": { - "errors": ["string"], - "warnings": ["string"] - }, - "status": "ok" - }, - "updated_at": "2019-08-24T14:15:22Z", - "version": "string", - "wildcard_hostname": "string" - } - ] + "regions": [ + { + "created_at": "2019-08-24T14:15:22Z", + "deleted": true, + "derp_enabled": true, + "derp_only": true, + "display_name": "string", + "healthy": true, + "icon_url": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "string", + "path_app_url": "string", + "status": { + "checked_at": "2019-08-24T14:15:22Z", + "report": { + "errors": ["string"], + "warnings": ["string"] + }, + "status": "ok" + }, + "updated_at": "2019-08-24T14:15:22Z", + "version": "string", + "wildcard_hostname": "string" + } + ] } ``` @@ -4439,13 +4439,13 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "created_at": "2019-08-24T14:15:22Z", - "database_latency": 0, - "error": "string", - "hostname": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "region_id": 0, - "relay_address": "string" + "created_at": "2019-08-24T14:15:22Z", + "database_latency": 0, + "error": "string", + "hostname": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "region_id": 0, + "relay_address": "string" } ``` @@ -4465,7 +4465,7 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "parameter_mismatch": true + "parameter_mismatch": true } ``` @@ -4509,14 +4509,14 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "detail": "string", - "message": "string", - "validations": [ - { - "detail": "string", - "field": "string" - } - ] + "detail": "string", + "message": "string", + "validations": [ + { + "detail": "string", + "field": "string" + } + ] } ``` @@ -4532,30 +4532,30 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "display_name": "string", - "name": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "organization_permissions": [ - { - "action": "application_connect", - "negate": true, - "resource_type": "*" - } - ], - "site_permissions": [ - { - "action": "application_connect", - "negate": true, - "resource_type": "*" - } - ], - "user_permissions": [ - { - "action": "application_connect", - "negate": true, - "resource_type": "*" - } - ] + "display_name": "string", + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "organization_permissions": [ + { + "action": "application_connect", + "negate": true, + "resource_type": "*" + } + ], + "site_permissions": [ + { + "action": "application_connect", + "negate": true, + "resource_type": "*" + } + ], + "user_permissions": [ + { + "action": "application_connect", + "negate": true, + "resource_type": "*" + } + ] } ``` @@ -4574,8 +4574,8 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "deploymentName": "string", - "sshconfigOptions": ["string"] + "deploymentName": "string", + "sshconfigOptions": ["string"] } ``` @@ -4590,11 +4590,11 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "hostname_prefix": "string", - "ssh_config_options": { - "property1": "string", - "property2": "string" - } + "hostname_prefix": "string", + "ssh_config_options": { + "property1": "string", + "property2": "string" + } } ``` @@ -4610,10 +4610,10 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "jetbrains": 0, - "reconnecting_pty": 0, - "ssh": 0, - "vscode": 0 + "jetbrains": 0, + "reconnecting_pty": 0, + "ssh": 0, + "vscode": 0 } ``` @@ -4630,9 +4630,9 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "default_duration": 0, - "disable_expiry_refresh": true, - "max_token_lifetime": 0 + "default_duration": 0, + "disable_expiry_refresh": true, + "max_token_lifetime": 0 } ``` @@ -4648,9 +4648,9 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "display_name": "string", - "name": "string", - "organization_id": "string" + "display_name": "string", + "name": "string", + "organization_id": "string" } ``` @@ -4666,15 +4666,15 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "links": { - "value": [ - { - "icon": "bug", - "name": "string", - "target": "string" - } - ] - } + "links": { + "value": [ + { + "icon": "bug", + "name": "string", + "target": "string" + } + ] + } } ``` @@ -4688,7 +4688,7 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "enable": true + "enable": true } ``` @@ -4702,21 +4702,21 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "address": { - "host": "string", - "port": "string" - }, - "allow_insecure_ciphers": true, - "cert_file": ["string"], - "client_auth": "string", - "client_ca_file": "string", - "client_cert_file": "string", - "client_key_file": "string", - "enable": true, - "key_file": ["string"], - "min_version": "string", - "redirect_http": true, - "supported_ciphers": ["string"] + "address": { + "host": "string", + "port": "string" + }, + "allow_insecure_ciphers": true, + "cert_file": ["string"], + "client_auth": "string", + "client_ca_file": "string", + "client_cert_file": "string", + "client_key_file": "string", + "enable": true, + "key_file": ["string"], + "min_version": "string", + "redirect_http": true, + "supported_ciphers": ["string"] } ``` @@ -4741,21 +4741,21 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "enable": true, - "trace": true, - "url": { - "forceQuery": true, - "fragment": "string", - "host": "string", - "omitHost": true, - "opaque": "string", - "path": "string", - "rawFragment": "string", - "rawPath": "string", - "rawQuery": "string", - "scheme": "string", - "user": {} - } + "enable": true, + "trace": true, + "url": { + "forceQuery": true, + "fragment": "string", + "host": "string", + "omitHost": true, + "opaque": "string", + "path": "string", + "rawFragment": "string", + "rawPath": "string", + "rawQuery": "string", + "scheme": "string", + "user": {} + } } ``` @@ -4771,51 +4771,51 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "active_user_count": 0, - "active_version_id": "eae64611-bd53-4a80-bb77-df1e432c0fbc", - "activity_bump_ms": 0, - "allow_user_autostart": true, - "allow_user_autostop": true, - "allow_user_cancel_workspace_jobs": true, - "autostart_requirement": { - "days_of_week": ["monday"] - }, - "autostop_requirement": { - "days_of_week": ["monday"], - "weeks": 0 - }, - "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, - "deprecated": true, - "deprecation_message": "string", - "description": "string", - "display_name": "string", - "failure_ttl_ms": 0, - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "max_port_share_level": "owner", - "name": "string", - "organization_display_name": "string", - "organization_icon": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "organization_name": "string", - "provisioner": "terraform", - "require_active_version": true, - "time_til_dormant_autodelete_ms": 0, - "time_til_dormant_ms": 0, - "updated_at": "2019-08-24T14:15:22Z" + "active_user_count": 0, + "active_version_id": "eae64611-bd53-4a80-bb77-df1e432c0fbc", + "activity_bump_ms": 0, + "allow_user_autostart": true, + "allow_user_autostop": true, + "allow_user_cancel_workspace_jobs": true, + "autostart_requirement": { + "days_of_week": ["monday"] + }, + "autostop_requirement": { + "days_of_week": ["monday"], + "weeks": 0 + }, + "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, + "deprecated": true, + "deprecation_message": "string", + "description": "string", + "display_name": "string", + "failure_ttl_ms": 0, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "max_port_share_level": "owner", + "name": "string", + "organization_display_name": "string", + "organization_icon": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "organization_name": "string", + "provisioner": "terraform", + "require_active_version": true, + "time_til_dormant_autodelete_ms": 0, + "time_til_dormant_ms": 0, + "updated_at": "2019-08-24T14:15:22Z" } ``` @@ -4865,13 +4865,13 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "display_name": "Visual Studio Code", - "icon": "string", - "seconds": 80500, - "slug": "vscode", - "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "times_used": 2, - "type": "builtin" + "display_name": "Visual Studio Code", + "icon": "string", + "seconds": 80500, + "slug": "vscode", + "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "times_used": 2, + "type": "builtin" } ``` @@ -4906,7 +4906,7 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "days_of_week": ["monday"] + "days_of_week": ["monday"] } ``` @@ -4920,8 +4920,8 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "days_of_week": ["monday"], - "weeks": 0 + "days_of_week": ["monday"], + "weeks": 0 } ``` @@ -4937,14 +4937,14 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "property1": { - "p50": 123, - "p95": 146 - }, - "property2": { - "p50": 123, - "p95": 146 - } + "property1": { + "p50": 123, + "p95": 146 + }, + "property2": { + "p50": 123, + "p95": 146 + } } ``` @@ -4958,13 +4958,13 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "description": "string", - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "markdown": "string", - "name": "string", - "tags": ["string"], - "url": "string" + "description": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "markdown": "string", + "name": "string", + "tags": ["string"], + "url": "string" } ``` @@ -4984,11 +4984,11 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "active_users": 14, - "end_time": "2019-08-24T14:15:22Z", - "interval": "week", - "start_time": "2019-08-24T14:15:22Z", - "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"] + "active_users": 14, + "end_time": "2019-08-24T14:15:22Z", + "interval": "week", + "start_time": "2019-08-24T14:15:22Z", + "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"] } ``` @@ -5006,44 +5006,44 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "active_users": 22, - "apps_usage": [ - { - "display_name": "Visual Studio Code", - "icon": "string", - "seconds": 80500, - "slug": "vscode", - "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "times_used": 2, - "type": "builtin" - } - ], - "end_time": "2019-08-24T14:15:22Z", - "parameters_usage": [ - { - "description": "string", - "display_name": "string", - "name": "string", - "options": [ - { - "description": "string", - "icon": "string", - "name": "string", - "value": "string" - } - ], - "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "type": "string", - "values": [ - { - "count": 0, - "value": "string" - } - ] - } - ], - "start_time": "2019-08-24T14:15:22Z", - "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"] + "active_users": 22, + "apps_usage": [ + { + "display_name": "Visual Studio Code", + "icon": "string", + "seconds": 80500, + "slug": "vscode", + "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "times_used": 2, + "type": "builtin" + } + ], + "end_time": "2019-08-24T14:15:22Z", + "parameters_usage": [ + { + "description": "string", + "display_name": "string", + "name": "string", + "options": [ + { + "description": "string", + "icon": "string", + "name": "string", + "value": "string" + } + ], + "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "type": "string", + "values": [ + { + "count": 0, + "value": "string" + } + ] + } + ], + "start_time": "2019-08-24T14:15:22Z", + "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"] } ``` @@ -5062,55 +5062,55 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "interval_reports": [ - { - "active_users": 14, - "end_time": "2019-08-24T14:15:22Z", - "interval": "week", - "start_time": "2019-08-24T14:15:22Z", - "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"] - } - ], - "report": { - "active_users": 22, - "apps_usage": [ - { - "display_name": "Visual Studio Code", - "icon": "string", - "seconds": 80500, - "slug": "vscode", - "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "times_used": 2, - "type": "builtin" - } - ], - "end_time": "2019-08-24T14:15:22Z", - "parameters_usage": [ - { - "description": "string", - "display_name": "string", - "name": "string", - "options": [ - { - "description": "string", - "icon": "string", - "name": "string", - "value": "string" - } - ], - "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "type": "string", - "values": [ - { - "count": 0, - "value": "string" - } - ] - } - ], - "start_time": "2019-08-24T14:15:22Z", - "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"] - } + "interval_reports": [ + { + "active_users": 14, + "end_time": "2019-08-24T14:15:22Z", + "interval": "week", + "start_time": "2019-08-24T14:15:22Z", + "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"] + } + ], + "report": { + "active_users": 22, + "apps_usage": [ + { + "display_name": "Visual Studio Code", + "icon": "string", + "seconds": 80500, + "slug": "vscode", + "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "times_used": 2, + "type": "builtin" + } + ], + "end_time": "2019-08-24T14:15:22Z", + "parameters_usage": [ + { + "description": "string", + "display_name": "string", + "name": "string", + "options": [ + { + "description": "string", + "icon": "string", + "name": "string", + "value": "string" + } + ], + "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "type": "string", + "values": [ + { + "count": 0, + "value": "string" + } + ] + } + ], + "start_time": "2019-08-24T14:15:22Z", + "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"] + } } ``` @@ -5125,25 +5125,25 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "description": "string", - "display_name": "string", - "name": "string", - "options": [ - { - "description": "string", - "icon": "string", - "name": "string", - "value": "string" - } - ], - "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "type": "string", - "values": [ - { - "count": 0, - "value": "string" - } - ] + "description": "string", + "display_name": "string", + "name": "string", + "options": [ + { + "description": "string", + "icon": "string", + "name": "string", + "value": "string" + } + ], + "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "type": "string", + "values": [ + { + "count": 0, + "value": "string" + } + ] } ``` @@ -5163,8 +5163,8 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "count": 0, - "value": "string" + "count": 0, + "value": "string" } ``` @@ -5195,26 +5195,26 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```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", - "login_type": "", - "name": "string", - "organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "role": "admin", - "roles": [ - { - "display_name": "string", - "name": "string", - "organization_id": "string" - } - ], - "status": "active", - "theme_preference": "string", - "updated_at": "2019-08-24T14:15:22Z", - "username": "string" + "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", + "login_type": "", + "name": "string", + "organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "role": "admin", + "roles": [ + { + "display_name": "string", + "name": "string", + "organization_id": "string" + } + ], + "status": "active", + "theme_preference": "string", + "updated_at": "2019-08-24T14:15:22Z", + "username": "string" } ``` @@ -5250,39 +5250,39 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "archived": true, - "created_at": "2019-08-24T14:15:22Z", - "created_by": { - "avatar_url": "http://example.com", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "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", - "error_code": "REQUIRED_TEMPLATE_VARIABLES", - "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "queue_position": 0, - "queue_size": 0, - "started_at": "2019-08-24T14:15:22Z", - "status": "pending", - "tags": { - "property1": "string", - "property2": "string" - }, - "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" - }, - "message": "string", - "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", - "warnings": ["UNSUPPORTED_WORKSPACES"] + "archived": true, + "created_at": "2019-08-24T14:15:22Z", + "created_by": { + "avatar_url": "http://example.com", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "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", + "error_code": "REQUIRED_TEMPLATE_VARIABLES", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "queue_position": 0, + "queue_size": 0, + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" + }, + "message": "string", + "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", + "warnings": ["UNSUPPORTED_WORKSPACES"] } ``` @@ -5307,13 +5307,13 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "authenticate_url": "string", - "authenticated": true, - "display_icon": "string", - "display_name": "string", - "id": "string", - "optional": true, - "type": "string" + "authenticate_url": "string", + "authenticated": true, + "display_icon": "string", + "display_name": "string", + "id": "string", + "optional": true, + "type": "string" } ``` @@ -5333,29 +5333,29 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "default_value": "string", - "description": "string", - "description_plaintext": "string", - "display_name": "string", - "ephemeral": true, - "icon": "string", - "mutable": true, - "name": "string", - "options": [ - { - "description": "string", - "icon": "string", - "name": "string", - "value": "string" - } - ], - "required": true, - "type": "string", - "validation_error": "string", - "validation_max": 0, - "validation_min": 0, - "validation_monotonic": "increasing", - "validation_regex": "string" + "default_value": "string", + "description": "string", + "description_plaintext": "string", + "display_name": "string", + "ephemeral": true, + "icon": "string", + "mutable": true, + "name": "string", + "options": [ + { + "description": "string", + "icon": "string", + "name": "string", + "value": "string" + } + ], + "required": true, + "type": "string", + "validation_error": "string", + "validation_max": 0, + "validation_min": 0, + "validation_monotonic": "increasing", + "validation_regex": "string" } ``` @@ -5395,10 +5395,10 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "description": "string", - "icon": "string", - "name": "string", - "value": "string" + "description": "string", + "icon": "string", + "name": "string", + "value": "string" } ``` @@ -5415,13 +5415,13 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "default_value": "string", - "description": "string", - "name": "string", - "required": true, - "sensitive": true, - "type": "string", - "value": "string" + "default_value": "string", + "description": "string", + "name": "string", + "required": true, + "sensitive": true, + "type": "string", + "value": "string" } ``` @@ -5463,7 +5463,7 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "max_token_lifetime": 0 + "max_token_lifetime": 0 } ``` @@ -5477,10 +5477,10 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "capture_logs": true, - "data_dog": true, - "enable": true, - "honeycomb_api_key": "string" + "capture_logs": true, + "data_dog": true, + "enable": true, + "honeycomb_api_key": "string" } ``` @@ -5497,8 +5497,8 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "p50": 123, - "p95": 146 + "p50": 123, + "p95": 146 } ``` @@ -5513,7 +5513,7 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08" + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08" } ``` @@ -5527,20 +5527,20 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "announcement_banners": [ - { - "background_color": "string", - "enabled": true, - "message": "string" - } - ], - "application_name": "string", - "logo_url": "string", - "service_banner": { - "background_color": "string", - "enabled": true, - "message": "string" - } + "announcement_banners": [ + { + "background_color": "string", + "enabled": true, + "message": "string" + } + ], + "application_name": "string", + "logo_url": "string", + "service_banner": { + "background_color": "string", + "enabled": true, + "message": "string" + } } ``` @@ -5557,9 +5557,9 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "current": true, - "url": "string", - "version": "string" + "current": true, + "url": "string", + "version": "string" } ``` @@ -5575,10 +5575,10 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "description": "string", - "display_name": "string", - "icon": "string", - "name": "string" + "description": "string", + "display_name": "string", + "icon": "string", + "name": "string" } ``` @@ -5595,7 +5595,7 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "roles": ["string"] + "roles": ["string"] } ``` @@ -5609,14 +5609,14 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "group_perms": { - "8bd26b20-f3e8-48be-a903-46bb920cf671": "use", - ">": "admin" - }, - "user_perms": { - "4df59e74-c027-470b-ab4d-cbba8963a5e9": "use", - "": "admin" - } + "group_perms": { + "8bd26b20-f3e8-48be-a903-46bb920cf671": "use", + ">": "admin" + }, + "user_perms": { + "4df59e74-c027-470b-ab4d-cbba8963a5e9": "use", + "": "admin" + } } ``` @@ -5633,7 +5633,7 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "theme_preference": "string" + "theme_preference": "string" } ``` @@ -5647,10 +5647,10 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "template_disabled_map": { - "property1": true, - "property2": true - } + "template_disabled_map": { + "property1": true, + "property2": true + } } ``` @@ -5665,8 +5665,8 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "old_password": "string", - "password": "string" + "old_password": "string", + "password": "string" } ``` @@ -5681,8 +5681,8 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "name": "string", - "username": "string" + "name": "string", + "username": "string" } ``` @@ -5697,7 +5697,7 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o ```json { - "schedule": "string" + "schedule": "string" } ``` @@ -5714,7 +5714,7 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "automatic_updates": "always" + "automatic_updates": "always" } ``` @@ -5728,7 +5728,7 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "schedule": "string" + "schedule": "string" } ``` @@ -5742,7 +5742,7 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "dormant": true + "dormant": true } ``` @@ -5756,7 +5756,7 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "name": "string" + "name": "string" } ``` @@ -5770,7 +5770,7 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "ttl_ms": 0 + "ttl_ms": 0 } ``` @@ -5784,7 +5784,7 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "hash": "19686d84-b10d-4f90-b18e-84fd3fa038fd" + "hash": "19686d84-b10d-4f90-b18e-84fd3fa038fd" } ``` @@ -5798,10 +5798,10 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "agent_name": "string", - "port": 0, - "protocol": "http", - "share_level": "owner" + "agent_name": "string", + "port": 0, + "protocol": "http", + "share_level": "owner" } ``` @@ -5845,25 +5845,25 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```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", - "login_type": "", - "name": "string", - "organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "roles": [ - { - "display_name": "string", - "name": "string", - "organization_id": "string" - } - ], - "status": "active", - "theme_preference": "string", - "updated_at": "2019-08-24T14:15:22Z", - "username": "string" + "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", + "login_type": "", + "name": "string", + "organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "roles": [ + { + "display_name": "string", + "name": "string", + "organization_id": "string" + } + ], + "status": "active", + "theme_preference": "string", + "updated_at": "2019-08-24T14:15:22Z", + "username": "string" } ``` @@ -5896,11 +5896,11 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "avatar_url": "http://example.com", - "seconds": 80500, - "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5", - "username": "string" + "avatar_url": "http://example.com", + "seconds": 80500, + "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5", + "username": "string" } ``` @@ -5918,18 +5918,18 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "end_time": "2019-08-24T14:15:22Z", - "start_time": "2019-08-24T14:15:22Z", - "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "users": [ - { - "avatar_url": "http://example.com", - "seconds": 80500, - "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5", - "username": "string" - } - ] + "end_time": "2019-08-24T14:15:22Z", + "start_time": "2019-08-24T14:15:22Z", + "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "users": [ + { + "avatar_url": "http://example.com", + "seconds": 80500, + "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5", + "username": "string" + } + ] } ``` @@ -5946,20 +5946,20 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "report": { - "end_time": "2019-08-24T14:15:22Z", - "start_time": "2019-08-24T14:15:22Z", - "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "users": [ - { - "avatar_url": "http://example.com", - "seconds": 80500, - "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5", - "username": "string" - } - ] - } + "report": { + "end_time": "2019-08-24T14:15:22Z", + "start_time": "2019-08-24T14:15:22Z", + "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "users": [ + { + "avatar_url": "http://example.com", + "seconds": 80500, + "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5", + "username": "string" + } + ] + } } ``` @@ -5973,14 +5973,14 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "avatar_url": "http://example.com", - "latency_ms": { - "p50": 31.312, - "p95": 119.832 - }, - "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5", - "username": "string" + "avatar_url": "http://example.com", + "latency_ms": { + "p50": 31.312, + "p95": 119.832 + }, + "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5", + "username": "string" } ``` @@ -5998,21 +5998,21 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "end_time": "2019-08-24T14:15:22Z", - "start_time": "2019-08-24T14:15:22Z", - "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "users": [ - { - "avatar_url": "http://example.com", - "latency_ms": { - "p50": 31.312, - "p95": 119.832 - }, - "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5", - "username": "string" - } - ] + "end_time": "2019-08-24T14:15:22Z", + "start_time": "2019-08-24T14:15:22Z", + "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "users": [ + { + "avatar_url": "http://example.com", + "latency_ms": { + "p50": 31.312, + "p95": 119.832 + }, + "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5", + "username": "string" + } + ] } ``` @@ -6029,23 +6029,23 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "report": { - "end_time": "2019-08-24T14:15:22Z", - "start_time": "2019-08-24T14:15:22Z", - "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "users": [ - { - "avatar_url": "http://example.com", - "latency_ms": { - "p50": 31.312, - "p95": 119.832 - }, - "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5", - "username": "string" - } - ] - } + "report": { + "end_time": "2019-08-24T14:15:22Z", + "start_time": "2019-08-24T14:15:22Z", + "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "users": [ + { + "avatar_url": "http://example.com", + "latency_ms": { + "p50": 31.312, + "p95": 119.832 + }, + "template_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5", + "username": "string" + } + ] + } } ``` @@ -6059,7 +6059,7 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "login_type": "" + "login_type": "" } ``` @@ -6073,8 +6073,8 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "name": "string", - "value": "string" + "name": "string", + "value": "string" } ``` @@ -6089,8 +6089,8 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "allow_user_custom": true, - "default_schedule": "string" + "allow_user_custom": true, + "default_schedule": "string" } ``` @@ -6105,12 +6105,12 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "next": "2019-08-24T14:15:22Z", - "raw_schedule": "string", - "time": "string", - "timezone": "string", - "user_can_set": true, - "user_set": true + "next": "2019-08-24T14:15:22Z", + "raw_schedule": "string", + "time": "string", + "timezone": "string", + "user_can_set": true, + "user_set": true } ``` @@ -6145,8 +6145,8 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "detail": "string", - "field": "string" + "detail": "string", + "field": "string" } ``` @@ -6176,8 +6176,8 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "name": "string", - "value": "string" + "name": "string", + "value": "string" } ``` @@ -6192,183 +6192,183 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "allow_renames": true, - "automatic_updates": "always", - "autostart_schedule": "string", - "created_at": "2019-08-24T14:15:22Z", - "deleting_at": "2019-08-24T14:15:22Z", - "dormant_at": "2019-08-24T14:15:22Z", - "favorite": true, - "health": { - "failing_agents": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "healthy": false - }, - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "last_used_at": "2019-08-24T14:15:22Z", - "latest_build": { - "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", - "error_code": "REQUIRED_TEMPLATE_VARIABLES", - "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "queue_position": 0, - "queue_size": 0, - "started_at": "2019-08-24T14:15:22Z", - "status": "pending", - "tags": { - "property1": "string", - "property2": "string" - }, - "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" - }, - "max_deadline": "2019-08-24T14:15:22Z", - "reason": "initiator", - "resources": [ - { - "agents": [ - { - "api_version": "string", - "apps": [ - { - "command": "string", - "display_name": "string", - "external": true, - "health": "disabled", - "healthcheck": { - "interval": 0, - "threshold": 0, - "url": "string" - }, - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "sharing_level": "owner", - "slug": "string", - "subdomain": true, - "subdomain_name": "string", - "url": "string" - } - ], - "architecture": "string", - "connection_timeout_seconds": 0, - "created_at": "2019-08-24T14:15:22Z", - "directory": "string", - "disconnected_at": "2019-08-24T14:15:22Z", - "display_apps": ["vscode"], - "environment_variables": { - "property1": "string", - "property2": "string" - }, - "expanded_directory": "string", - "first_connected_at": "2019-08-24T14:15:22Z", - "health": { - "healthy": false, - "reason": "agent has lost connection" - }, - "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 - } - }, - "lifecycle_state": "created", - "log_sources": [ - { - "created_at": "2019-08-24T14:15:22Z", - "display_name": "string", - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" - } - ], - "logs_length": 0, - "logs_overflowed": true, - "name": "string", - "operating_system": "string", - "ready_at": "2019-08-24T14:15:22Z", - "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", - "scripts": [ - { - "cron": "string", - "log_path": "string", - "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", - "run_on_start": true, - "run_on_stop": true, - "script": "string", - "start_blocks_login": true, - "timeout": 0 - } - ], - "started_at": "2019-08-24T14:15:22Z", - "startup_script_behavior": "blocking", - "status": "connecting", - "subsystems": ["envbox"], - "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_avatar_url": "string", - "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7", - "workspace_owner_name": "string" - }, - "name": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "organization_name": "string", - "outdated": true, - "owner_avatar_url": "string", - "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05", - "owner_name": "string", - "template_active_version_id": "b0da9c29-67d8-4c87-888c-bafe356f7f3c", - "template_allow_user_cancel_workspace_jobs": true, - "template_display_name": "string", - "template_icon": "string", - "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", - "template_name": "string", - "template_require_active_version": true, - "ttl_ms": 0, - "updated_at": "2019-08-24T14:15:22Z" + "allow_renames": true, + "automatic_updates": "always", + "autostart_schedule": "string", + "created_at": "2019-08-24T14:15:22Z", + "deleting_at": "2019-08-24T14:15:22Z", + "dormant_at": "2019-08-24T14:15:22Z", + "favorite": true, + "health": { + "failing_agents": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "healthy": false + }, + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "last_used_at": "2019-08-24T14:15:22Z", + "latest_build": { + "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", + "error_code": "REQUIRED_TEMPLATE_VARIABLES", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "queue_position": 0, + "queue_size": 0, + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" + }, + "max_deadline": "2019-08-24T14:15:22Z", + "reason": "initiator", + "resources": [ + { + "agents": [ + { + "api_version": "string", + "apps": [ + { + "command": "string", + "display_name": "string", + "external": true, + "health": "disabled", + "healthcheck": { + "interval": 0, + "threshold": 0, + "url": "string" + }, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "sharing_level": "owner", + "slug": "string", + "subdomain": true, + "subdomain_name": "string", + "url": "string" + } + ], + "architecture": "string", + "connection_timeout_seconds": 0, + "created_at": "2019-08-24T14:15:22Z", + "directory": "string", + "disconnected_at": "2019-08-24T14:15:22Z", + "display_apps": ["vscode"], + "environment_variables": { + "property1": "string", + "property2": "string" + }, + "expanded_directory": "string", + "first_connected_at": "2019-08-24T14:15:22Z", + "health": { + "healthy": false, + "reason": "agent has lost connection" + }, + "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 + } + }, + "lifecycle_state": "created", + "log_sources": [ + { + "created_at": "2019-08-24T14:15:22Z", + "display_name": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" + } + ], + "logs_length": 0, + "logs_overflowed": true, + "name": "string", + "operating_system": "string", + "ready_at": "2019-08-24T14:15:22Z", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", + "scripts": [ + { + "cron": "string", + "log_path": "string", + "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", + "run_on_start": true, + "run_on_stop": true, + "script": "string", + "start_blocks_login": true, + "timeout": 0 + } + ], + "started_at": "2019-08-24T14:15:22Z", + "startup_script_behavior": "blocking", + "status": "connecting", + "subsystems": ["envbox"], + "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_avatar_url": "string", + "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7", + "workspace_owner_name": "string" + }, + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "organization_name": "string", + "outdated": true, + "owner_avatar_url": "string", + "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05", + "owner_name": "string", + "template_active_version_id": "b0da9c29-67d8-4c87-888c-bafe356f7f3c", + "template_allow_user_cancel_workspace_jobs": true, + "template_display_name": "string", + "template_icon": "string", + "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", + "template_name": "string", + "template_require_active_version": true, + "ttl_ms": 0, + "updated_at": "2019-08-24T14:15:22Z" } ``` @@ -6415,91 +6415,91 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "api_version": "string", - "apps": [ - { - "command": "string", - "display_name": "string", - "external": true, - "health": "disabled", - "healthcheck": { - "interval": 0, - "threshold": 0, - "url": "string" - }, - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "sharing_level": "owner", - "slug": "string", - "subdomain": true, - "subdomain_name": "string", - "url": "string" - } - ], - "architecture": "string", - "connection_timeout_seconds": 0, - "created_at": "2019-08-24T14:15:22Z", - "directory": "string", - "disconnected_at": "2019-08-24T14:15:22Z", - "display_apps": ["vscode"], - "environment_variables": { - "property1": "string", - "property2": "string" - }, - "expanded_directory": "string", - "first_connected_at": "2019-08-24T14:15:22Z", - "health": { - "healthy": false, - "reason": "agent has lost connection" - }, - "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 - } - }, - "lifecycle_state": "created", - "log_sources": [ - { - "created_at": "2019-08-24T14:15:22Z", - "display_name": "string", - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" - } - ], - "logs_length": 0, - "logs_overflowed": true, - "name": "string", - "operating_system": "string", - "ready_at": "2019-08-24T14:15:22Z", - "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", - "scripts": [ - { - "cron": "string", - "log_path": "string", - "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", - "run_on_start": true, - "run_on_stop": true, - "script": "string", - "start_blocks_login": true, - "timeout": 0 - } - ], - "started_at": "2019-08-24T14:15:22Z", - "startup_script_behavior": "blocking", - "status": "connecting", - "subsystems": ["envbox"], - "troubleshooting_url": "string", - "updated_at": "2019-08-24T14:15:22Z", - "version": "string" + "api_version": "string", + "apps": [ + { + "command": "string", + "display_name": "string", + "external": true, + "health": "disabled", + "healthcheck": { + "interval": 0, + "threshold": 0, + "url": "string" + }, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "sharing_level": "owner", + "slug": "string", + "subdomain": true, + "subdomain_name": "string", + "url": "string" + } + ], + "architecture": "string", + "connection_timeout_seconds": 0, + "created_at": "2019-08-24T14:15:22Z", + "directory": "string", + "disconnected_at": "2019-08-24T14:15:22Z", + "display_apps": ["vscode"], + "environment_variables": { + "property1": "string", + "property2": "string" + }, + "expanded_directory": "string", + "first_connected_at": "2019-08-24T14:15:22Z", + "health": { + "healthy": false, + "reason": "agent has lost connection" + }, + "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 + } + }, + "lifecycle_state": "created", + "log_sources": [ + { + "created_at": "2019-08-24T14:15:22Z", + "display_name": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" + } + ], + "logs_length": 0, + "logs_overflowed": true, + "name": "string", + "operating_system": "string", + "ready_at": "2019-08-24T14:15:22Z", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", + "scripts": [ + { + "cron": "string", + "log_path": "string", + "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", + "run_on_start": true, + "run_on_stop": true, + "script": "string", + "start_blocks_login": true, + "timeout": 0 + } + ], + "started_at": "2019-08-24T14:15:22Z", + "startup_script_behavior": "blocking", + "status": "connecting", + "subsystems": ["envbox"], + "troubleshooting_url": "string", + "updated_at": "2019-08-24T14:15:22Z", + "version": "string" } ``` @@ -6546,8 +6546,8 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "healthy": false, - "reason": "agent has lost connection" + "healthy": false, + "reason": "agent has lost connection" } ``` @@ -6584,9 +6584,9 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "network": "string", - "port": 0, - "process_name": "string" + "network": "string", + "port": 0, + "process_name": "string" } ``` @@ -6602,13 +6602,13 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "ports": [ - { - "network": "string", - "port": 0, - "process_name": "string" - } - ] + "ports": [ + { + "network": "string", + "port": 0, + "process_name": "string" + } + ] } ``` @@ -6622,11 +6622,11 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "created_at": "2019-08-24T14:15:22Z", - "id": 0, - "level": "trace", - "output": "string", - "source_id": "ae50a35c-df42-4eff-ba26-f8bc28d2af81" + "created_at": "2019-08-24T14:15:22Z", + "id": 0, + "level": "trace", + "output": "string", + "source_id": "ae50a35c-df42-4eff-ba26-f8bc28d2af81" } ``` @@ -6644,11 +6644,11 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "created_at": "2019-08-24T14:15:22Z", - "display_name": "string", - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" + "created_at": "2019-08-24T14:15:22Z", + "display_name": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" } ``` @@ -6666,11 +6666,11 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "agent_name": "string", - "port": 0, - "protocol": "http", - "share_level": "owner", - "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9" + "agent_name": "string", + "port": 0, + "protocol": "http", + "share_level": "owner", + "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9" } ``` @@ -6729,15 +6729,15 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "shares": [ - { - "agent_name": "string", - "port": 0, - "protocol": "http", - "share_level": "owner", - "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9" - } - ] + "shares": [ + { + "agent_name": "string", + "port": 0, + "protocol": "http", + "share_level": "owner", + "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9" + } + ] } ``` @@ -6751,14 +6751,14 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "cron": "string", - "log_path": "string", - "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", - "run_on_start": true, - "run_on_stop": true, - "script": "string", - "start_blocks_login": true, - "timeout": 0 + "cron": "string", + "log_path": "string", + "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", + "run_on_start": true, + "run_on_stop": true, + "script": "string", + "start_blocks_login": true, + "timeout": 0 } ``` @@ -6811,22 +6811,22 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "command": "string", - "display_name": "string", - "external": true, - "health": "disabled", - "healthcheck": { - "interval": 0, - "threshold": 0, - "url": "string" - }, - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "sharing_level": "owner", - "slug": "string", - "subdomain": true, - "subdomain_name": "string", - "url": "string" + "command": "string", + "display_name": "string", + "external": true, + "health": "disabled", + "healthcheck": { + "interval": 0, + "threshold": 0, + "url": "string" + }, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "sharing_level": "owner", + "slug": "string", + "subdomain": true, + "subdomain_name": "string", + "url": "string" } ``` @@ -6892,152 +6892,152 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```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", - "error_code": "REQUIRED_TEMPLATE_VARIABLES", - "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "queue_position": 0, - "queue_size": 0, - "started_at": "2019-08-24T14:15:22Z", - "status": "pending", - "tags": { - "property1": "string", - "property2": "string" - }, - "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" - }, - "max_deadline": "2019-08-24T14:15:22Z", - "reason": "initiator", - "resources": [ - { - "agents": [ - { - "api_version": "string", - "apps": [ - { - "command": "string", - "display_name": "string", - "external": true, - "health": "disabled", - "healthcheck": { - "interval": 0, - "threshold": 0, - "url": "string" - }, - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "sharing_level": "owner", - "slug": "string", - "subdomain": true, - "subdomain_name": "string", - "url": "string" - } - ], - "architecture": "string", - "connection_timeout_seconds": 0, - "created_at": "2019-08-24T14:15:22Z", - "directory": "string", - "disconnected_at": "2019-08-24T14:15:22Z", - "display_apps": ["vscode"], - "environment_variables": { - "property1": "string", - "property2": "string" - }, - "expanded_directory": "string", - "first_connected_at": "2019-08-24T14:15:22Z", - "health": { - "healthy": false, - "reason": "agent has lost connection" - }, - "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 - } - }, - "lifecycle_state": "created", - "log_sources": [ - { - "created_at": "2019-08-24T14:15:22Z", - "display_name": "string", - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" - } - ], - "logs_length": 0, - "logs_overflowed": true, - "name": "string", - "operating_system": "string", - "ready_at": "2019-08-24T14:15:22Z", - "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", - "scripts": [ - { - "cron": "string", - "log_path": "string", - "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", - "run_on_start": true, - "run_on_stop": true, - "script": "string", - "start_blocks_login": true, - "timeout": 0 - } - ], - "started_at": "2019-08-24T14:15:22Z", - "startup_script_behavior": "blocking", - "status": "connecting", - "subsystems": ["envbox"], - "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_avatar_url": "string", - "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7", - "workspace_owner_name": "string" + "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", + "error_code": "REQUIRED_TEMPLATE_VARIABLES", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "queue_position": 0, + "queue_size": 0, + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" + }, + "max_deadline": "2019-08-24T14:15:22Z", + "reason": "initiator", + "resources": [ + { + "agents": [ + { + "api_version": "string", + "apps": [ + { + "command": "string", + "display_name": "string", + "external": true, + "health": "disabled", + "healthcheck": { + "interval": 0, + "threshold": 0, + "url": "string" + }, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "sharing_level": "owner", + "slug": "string", + "subdomain": true, + "subdomain_name": "string", + "url": "string" + } + ], + "architecture": "string", + "connection_timeout_seconds": 0, + "created_at": "2019-08-24T14:15:22Z", + "directory": "string", + "disconnected_at": "2019-08-24T14:15:22Z", + "display_apps": ["vscode"], + "environment_variables": { + "property1": "string", + "property2": "string" + }, + "expanded_directory": "string", + "first_connected_at": "2019-08-24T14:15:22Z", + "health": { + "healthy": false, + "reason": "agent has lost connection" + }, + "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 + } + }, + "lifecycle_state": "created", + "log_sources": [ + { + "created_at": "2019-08-24T14:15:22Z", + "display_name": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" + } + ], + "logs_length": 0, + "logs_overflowed": true, + "name": "string", + "operating_system": "string", + "ready_at": "2019-08-24T14:15:22Z", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", + "scripts": [ + { + "cron": "string", + "log_path": "string", + "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", + "run_on_start": true, + "run_on_stop": true, + "script": "string", + "start_blocks_login": true, + "timeout": 0 + } + ], + "started_at": "2019-08-24T14:15:22Z", + "startup_script_behavior": "blocking", + "status": "connecting", + "subsystems": ["envbox"], + "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_avatar_url": "string", + "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7", + "workspace_owner_name": "string" } ``` @@ -7092,8 +7092,8 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "name": "string", - "value": "string" + "name": "string", + "value": "string" } ``` @@ -7108,8 +7108,8 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "p50": 0, - "p95": 0 + "p50": 0, + "p95": 0 } ``` @@ -7124,17 +7124,17 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "building": 0, - "connection_latency_ms": { - "p50": 0, - "p95": 0 - }, - "failed": 0, - "pending": 0, - "running": 0, - "rx_bytes": 0, - "stopped": 0, - "tx_bytes": 0 + "building": 0, + "connection_latency_ms": { + "p50": 0, + "p95": 0 + }, + "failed": 0, + "pending": 0, + "running": 0, + "rx_bytes": 0, + "stopped": 0, + "tx_bytes": 0 } ``` @@ -7155,8 +7155,8 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "failing_agents": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "healthy": false + "failing_agents": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "healthy": false } ``` @@ -7171,27 +7171,27 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "created_at": "2019-08-24T14:15:22Z", - "deleted": true, - "derp_enabled": true, - "derp_only": true, - "display_name": "string", - "healthy": true, - "icon_url": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "name": "string", - "path_app_url": "string", - "status": { - "checked_at": "2019-08-24T14:15:22Z", - "report": { - "errors": ["string"], - "warnings": ["string"] - }, - "status": "ok" - }, - "updated_at": "2019-08-24T14:15:22Z", - "version": "string", - "wildcard_hostname": "string" + "created_at": "2019-08-24T14:15:22Z", + "deleted": true, + "derp_enabled": true, + "derp_only": true, + "display_name": "string", + "healthy": true, + "icon_url": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "string", + "path_app_url": "string", + "status": { + "checked_at": "2019-08-24T14:15:22Z", + "report": { + "errors": ["string"], + "warnings": ["string"] + }, + "status": "ok" + }, + "updated_at": "2019-08-24T14:15:22Z", + "version": "string", + "wildcard_hostname": "string" } ``` @@ -7218,12 +7218,12 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "checked_at": "2019-08-24T14:15:22Z", - "report": { - "errors": ["string"], - "warnings": ["string"] - }, - "status": "ok" + "checked_at": "2019-08-24T14:15:22Z", + "report": { + "errors": ["string"], + "warnings": ["string"] + }, + "status": "ok" } ``` @@ -7239,8 +7239,8 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "budget": 0, - "credits_consumed": 0 + "budget": 0, + "credits_consumed": 0 } ``` @@ -7255,111 +7255,111 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "agents": [ - { - "api_version": "string", - "apps": [ - { - "command": "string", - "display_name": "string", - "external": true, - "health": "disabled", - "healthcheck": { - "interval": 0, - "threshold": 0, - "url": "string" - }, - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "sharing_level": "owner", - "slug": "string", - "subdomain": true, - "subdomain_name": "string", - "url": "string" - } - ], - "architecture": "string", - "connection_timeout_seconds": 0, - "created_at": "2019-08-24T14:15:22Z", - "directory": "string", - "disconnected_at": "2019-08-24T14:15:22Z", - "display_apps": ["vscode"], - "environment_variables": { - "property1": "string", - "property2": "string" - }, - "expanded_directory": "string", - "first_connected_at": "2019-08-24T14:15:22Z", - "health": { - "healthy": false, - "reason": "agent has lost connection" - }, - "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 - } - }, - "lifecycle_state": "created", - "log_sources": [ - { - "created_at": "2019-08-24T14:15:22Z", - "display_name": "string", - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" - } - ], - "logs_length": 0, - "logs_overflowed": true, - "name": "string", - "operating_system": "string", - "ready_at": "2019-08-24T14:15:22Z", - "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", - "scripts": [ - { - "cron": "string", - "log_path": "string", - "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", - "run_on_start": true, - "run_on_stop": true, - "script": "string", - "start_blocks_login": true, - "timeout": 0 - } - ], - "started_at": "2019-08-24T14:15:22Z", - "startup_script_behavior": "blocking", - "status": "connecting", - "subsystems": ["envbox"], - "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" + "agents": [ + { + "api_version": "string", + "apps": [ + { + "command": "string", + "display_name": "string", + "external": true, + "health": "disabled", + "healthcheck": { + "interval": 0, + "threshold": 0, + "url": "string" + }, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "sharing_level": "owner", + "slug": "string", + "subdomain": true, + "subdomain_name": "string", + "url": "string" + } + ], + "architecture": "string", + "connection_timeout_seconds": 0, + "created_at": "2019-08-24T14:15:22Z", + "directory": "string", + "disconnected_at": "2019-08-24T14:15:22Z", + "display_apps": ["vscode"], + "environment_variables": { + "property1": "string", + "property2": "string" + }, + "expanded_directory": "string", + "first_connected_at": "2019-08-24T14:15:22Z", + "health": { + "healthy": false, + "reason": "agent has lost connection" + }, + "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 + } + }, + "lifecycle_state": "created", + "log_sources": [ + { + "created_at": "2019-08-24T14:15:22Z", + "display_name": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" + } + ], + "logs_length": 0, + "logs_overflowed": true, + "name": "string", + "operating_system": "string", + "ready_at": "2019-08-24T14:15:22Z", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", + "scripts": [ + { + "cron": "string", + "log_path": "string", + "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", + "run_on_start": true, + "run_on_stop": true, + "script": "string", + "start_blocks_login": true, + "timeout": 0 + } + ], + "started_at": "2019-08-24T14:15:22Z", + "startup_script_behavior": "blocking", + "status": "connecting", + "subsystems": ["envbox"], + "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" } ``` @@ -7391,9 +7391,9 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "key": "string", - "sensitive": true, - "value": "string" + "key": "string", + "sensitive": true, + "value": "string" } ``` @@ -7448,184 +7448,184 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "count": 0, - "workspaces": [ - { - "allow_renames": true, - "automatic_updates": "always", - "autostart_schedule": "string", - "created_at": "2019-08-24T14:15:22Z", - "deleting_at": "2019-08-24T14:15:22Z", - "dormant_at": "2019-08-24T14:15:22Z", - "favorite": true, - "health": { - "failing_agents": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "healthy": false - }, - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "last_used_at": "2019-08-24T14:15:22Z", - "latest_build": { - "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", - "error_code": "REQUIRED_TEMPLATE_VARIABLES", - "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "queue_position": 0, - "queue_size": 0, - "started_at": "2019-08-24T14:15:22Z", - "status": "pending", - "tags": { - "property1": "string", - "property2": "string" - }, - "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" - }, - "max_deadline": "2019-08-24T14:15:22Z", - "reason": "initiator", - "resources": [ - { - "agents": [ - { - "api_version": "string", - "apps": [ - { - "command": "string", - "display_name": "string", - "external": true, - "health": "disabled", - "healthcheck": {}, - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "sharing_level": "owner", - "slug": "string", - "subdomain": true, - "subdomain_name": "string", - "url": "string" - } - ], - "architecture": "string", - "connection_timeout_seconds": 0, - "created_at": "2019-08-24T14:15:22Z", - "directory": "string", - "disconnected_at": "2019-08-24T14:15:22Z", - "display_apps": ["vscode"], - "environment_variables": { - "property1": "string", - "property2": "string" - }, - "expanded_directory": "string", - "first_connected_at": "2019-08-24T14:15:22Z", - "health": { - "healthy": false, - "reason": "agent has lost connection" - }, - "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 - } - }, - "lifecycle_state": "created", - "log_sources": [ - { - "created_at": "2019-08-24T14:15:22Z", - "display_name": "string", - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" - } - ], - "logs_length": 0, - "logs_overflowed": true, - "name": "string", - "operating_system": "string", - "ready_at": "2019-08-24T14:15:22Z", - "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", - "scripts": [ - { - "cron": "string", - "log_path": "string", - "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", - "run_on_start": true, - "run_on_stop": true, - "script": "string", - "start_blocks_login": true, - "timeout": 0 - } - ], - "started_at": "2019-08-24T14:15:22Z", - "startup_script_behavior": "blocking", - "status": "connecting", - "subsystems": ["envbox"], - "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_avatar_url": "string", - "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7", - "workspace_owner_name": "string" - }, - "name": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "organization_name": "string", - "outdated": true, - "owner_avatar_url": "string", - "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05", - "owner_name": "string", - "template_active_version_id": "b0da9c29-67d8-4c87-888c-bafe356f7f3c", - "template_allow_user_cancel_workspace_jobs": true, - "template_display_name": "string", - "template_icon": "string", - "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", - "template_name": "string", - "template_require_active_version": true, - "ttl_ms": 0, - "updated_at": "2019-08-24T14:15:22Z" - } - ] + "count": 0, + "workspaces": [ + { + "allow_renames": true, + "automatic_updates": "always", + "autostart_schedule": "string", + "created_at": "2019-08-24T14:15:22Z", + "deleting_at": "2019-08-24T14:15:22Z", + "dormant_at": "2019-08-24T14:15:22Z", + "favorite": true, + "health": { + "failing_agents": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "healthy": false + }, + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "last_used_at": "2019-08-24T14:15:22Z", + "latest_build": { + "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", + "error_code": "REQUIRED_TEMPLATE_VARIABLES", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "queue_position": 0, + "queue_size": 0, + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" + }, + "max_deadline": "2019-08-24T14:15:22Z", + "reason": "initiator", + "resources": [ + { + "agents": [ + { + "api_version": "string", + "apps": [ + { + "command": "string", + "display_name": "string", + "external": true, + "health": "disabled", + "healthcheck": {}, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "sharing_level": "owner", + "slug": "string", + "subdomain": true, + "subdomain_name": "string", + "url": "string" + } + ], + "architecture": "string", + "connection_timeout_seconds": 0, + "created_at": "2019-08-24T14:15:22Z", + "directory": "string", + "disconnected_at": "2019-08-24T14:15:22Z", + "display_apps": ["vscode"], + "environment_variables": { + "property1": "string", + "property2": "string" + }, + "expanded_directory": "string", + "first_connected_at": "2019-08-24T14:15:22Z", + "health": { + "healthy": false, + "reason": "agent has lost connection" + }, + "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 + } + }, + "lifecycle_state": "created", + "log_sources": [ + { + "created_at": "2019-08-24T14:15:22Z", + "display_name": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" + } + ], + "logs_length": 0, + "logs_overflowed": true, + "name": "string", + "operating_system": "string", + "ready_at": "2019-08-24T14:15:22Z", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", + "scripts": [ + { + "cron": "string", + "log_path": "string", + "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", + "run_on_start": true, + "run_on_stop": true, + "script": "string", + "start_blocks_login": true, + "timeout": 0 + } + ], + "started_at": "2019-08-24T14:15:22Z", + "startup_script_behavior": "blocking", + "status": "connecting", + "subsystems": ["envbox"], + "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_avatar_url": "string", + "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7", + "workspace_owner_name": "string" + }, + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "organization_name": "string", + "outdated": true, + "owner_avatar_url": "string", + "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05", + "owner_name": "string", + "template_active_version_id": "b0da9c29-67d8-4c87-888c-bafe356f7f3c", + "template_allow_user_cancel_workspace_jobs": true, + "template_display_name": "string", + "template_icon": "string", + "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", + "template_name": "string", + "template_require_active_version": true, + "ttl_ms": 0, + "updated_at": "2019-08-24T14:15:22Z" + } + ] } ``` @@ -7640,9 +7640,9 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "key": {}, - "recv": 0, - "sent": 0 + "key": {}, + "recv": 0, + "sent": 0 } ``` @@ -7658,8 +7658,8 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "tokenBucketBytesBurst": 0, - "tokenBucketBytesPerSecond": 0 + "tokenBucketBytesBurst": 0, + "tokenBucketBytesPerSecond": 0 } ``` @@ -7707,8 +7707,8 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "code": "EUNKNOWN", - "message": "string" + "code": "EUNKNOWN", + "message": "string" } ``` @@ -7739,20 +7739,20 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "access_url": "string", - "dismissed": true, - "error": "string", - "healthy": true, - "healthz_response": "string", - "reachable": true, - "severity": "ok", - "status_code": 0, - "warnings": [ - { - "code": "EUNKNOWN", - "message": "string" - } - ] + "access_url": "string", + "dismissed": true, + "error": "string", + "healthy": true, + "healthz_response": "string", + "reachable": true, + "severity": "ok", + "status_code": 0, + "warnings": [ + { + "code": "EUNKNOWN", + "message": "string" + } + ] } ``` @@ -7782,206 +7782,206 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "dismissed": true, - "error": "string", - "healthy": true, - "netcheck": { - "captivePortal": "string", - "globalV4": "string", - "globalV6": "string", - "hairPinning": "string", - "icmpv4": true, - "ipv4": true, - "ipv4CanSend": true, - "ipv6": true, - "ipv6CanSend": true, - "mappingVariesByDestIP": "string", - "oshasIPv6": true, - "pcp": "string", - "pmp": "string", - "preferredDERP": 0, - "regionLatency": { - "property1": 0, - "property2": 0 - }, - "regionV4Latency": { - "property1": 0, - "property2": 0 - }, - "regionV6Latency": { - "property1": 0, - "property2": 0 - }, - "udp": true, - "upnP": "string" - }, - "netcheck_err": "string", - "netcheck_logs": ["string"], - "regions": { - "property1": { - "error": "string", - "healthy": true, - "node_reports": [ - { - "can_exchange_messages": true, - "client_errs": [["string"]], - "client_logs": [["string"]], - "error": "string", - "healthy": true, - "node": { - "canPort80": true, - "certName": "string", - "derpport": 0, - "forceHTTP": true, - "hostName": "string", - "insecureForTests": true, - "ipv4": "string", - "ipv6": "string", - "name": "string", - "regionID": 0, - "stunonly": true, - "stunport": 0, - "stuntestIP": "string" - }, - "node_info": { - "tokenBucketBytesBurst": 0, - "tokenBucketBytesPerSecond": 0 - }, - "round_trip_ping": "string", - "round_trip_ping_ms": 0, - "severity": "ok", - "stun": { - "canSTUN": true, - "enabled": true, - "error": "string" - }, - "uses_websocket": true, - "warnings": [ - { - "code": "EUNKNOWN", - "message": "string" - } - ] - } - ], - "region": { - "avoid": true, - "embeddedRelay": true, - "nodes": [ - { - "canPort80": true, - "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" - }, - "severity": "ok", - "warnings": [ - { - "code": "EUNKNOWN", - "message": "string" - } - ] - }, - "property2": { - "error": "string", - "healthy": true, - "node_reports": [ - { - "can_exchange_messages": true, - "client_errs": [["string"]], - "client_logs": [["string"]], - "error": "string", - "healthy": true, - "node": { - "canPort80": true, - "certName": "string", - "derpport": 0, - "forceHTTP": true, - "hostName": "string", - "insecureForTests": true, - "ipv4": "string", - "ipv6": "string", - "name": "string", - "regionID": 0, - "stunonly": true, - "stunport": 0, - "stuntestIP": "string" - }, - "node_info": { - "tokenBucketBytesBurst": 0, - "tokenBucketBytesPerSecond": 0 - }, - "round_trip_ping": "string", - "round_trip_ping_ms": 0, - "severity": "ok", - "stun": { - "canSTUN": true, - "enabled": true, - "error": "string" - }, - "uses_websocket": true, - "warnings": [ - { - "code": "EUNKNOWN", - "message": "string" - } - ] - } - ], - "region": { - "avoid": true, - "embeddedRelay": true, - "nodes": [ - { - "canPort80": true, - "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" - }, - "severity": "ok", - "warnings": [ - { - "code": "EUNKNOWN", - "message": "string" - } - ] - } - }, - "severity": "ok", - "warnings": [ - { - "code": "EUNKNOWN", - "message": "string" - } - ] + "dismissed": true, + "error": "string", + "healthy": true, + "netcheck": { + "captivePortal": "string", + "globalV4": "string", + "globalV6": "string", + "hairPinning": "string", + "icmpv4": true, + "ipv4": true, + "ipv4CanSend": true, + "ipv6": true, + "ipv6CanSend": true, + "mappingVariesByDestIP": "string", + "oshasIPv6": true, + "pcp": "string", + "pmp": "string", + "preferredDERP": 0, + "regionLatency": { + "property1": 0, + "property2": 0 + }, + "regionV4Latency": { + "property1": 0, + "property2": 0 + }, + "regionV6Latency": { + "property1": 0, + "property2": 0 + }, + "udp": true, + "upnP": "string" + }, + "netcheck_err": "string", + "netcheck_logs": ["string"], + "regions": { + "property1": { + "error": "string", + "healthy": true, + "node_reports": [ + { + "can_exchange_messages": true, + "client_errs": [["string"]], + "client_logs": [["string"]], + "error": "string", + "healthy": true, + "node": { + "canPort80": true, + "certName": "string", + "derpport": 0, + "forceHTTP": true, + "hostName": "string", + "insecureForTests": true, + "ipv4": "string", + "ipv6": "string", + "name": "string", + "regionID": 0, + "stunonly": true, + "stunport": 0, + "stuntestIP": "string" + }, + "node_info": { + "tokenBucketBytesBurst": 0, + "tokenBucketBytesPerSecond": 0 + }, + "round_trip_ping": "string", + "round_trip_ping_ms": 0, + "severity": "ok", + "stun": { + "canSTUN": true, + "enabled": true, + "error": "string" + }, + "uses_websocket": true, + "warnings": [ + { + "code": "EUNKNOWN", + "message": "string" + } + ] + } + ], + "region": { + "avoid": true, + "embeddedRelay": true, + "nodes": [ + { + "canPort80": true, + "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" + }, + "severity": "ok", + "warnings": [ + { + "code": "EUNKNOWN", + "message": "string" + } + ] + }, + "property2": { + "error": "string", + "healthy": true, + "node_reports": [ + { + "can_exchange_messages": true, + "client_errs": [["string"]], + "client_logs": [["string"]], + "error": "string", + "healthy": true, + "node": { + "canPort80": true, + "certName": "string", + "derpport": 0, + "forceHTTP": true, + "hostName": "string", + "insecureForTests": true, + "ipv4": "string", + "ipv6": "string", + "name": "string", + "regionID": 0, + "stunonly": true, + "stunport": 0, + "stuntestIP": "string" + }, + "node_info": { + "tokenBucketBytesBurst": 0, + "tokenBucketBytesPerSecond": 0 + }, + "round_trip_ping": "string", + "round_trip_ping_ms": 0, + "severity": "ok", + "stun": { + "canSTUN": true, + "enabled": true, + "error": "string" + }, + "uses_websocket": true, + "warnings": [ + { + "code": "EUNKNOWN", + "message": "string" + } + ] + } + ], + "region": { + "avoid": true, + "embeddedRelay": true, + "nodes": [ + { + "canPort80": true, + "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" + }, + "severity": "ok", + "warnings": [ + { + "code": "EUNKNOWN", + "message": "string" + } + ] + } + }, + "severity": "ok", + "warnings": [ + { + "code": "EUNKNOWN", + "message": "string" + } + ] } ``` @@ -8012,45 +8012,45 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "can_exchange_messages": true, - "client_errs": [["string"]], - "client_logs": [["string"]], - "error": "string", - "healthy": true, - "node": { - "canPort80": true, - "certName": "string", - "derpport": 0, - "forceHTTP": true, - "hostName": "string", - "insecureForTests": true, - "ipv4": "string", - "ipv6": "string", - "name": "string", - "regionID": 0, - "stunonly": true, - "stunport": 0, - "stuntestIP": "string" - }, - "node_info": { - "tokenBucketBytesBurst": 0, - "tokenBucketBytesPerSecond": 0 - }, - "round_trip_ping": "string", - "round_trip_ping_ms": 0, - "severity": "ok", - "stun": { - "canSTUN": true, - "enabled": true, - "error": "string" - }, - "uses_websocket": true, - "warnings": [ - { - "code": "EUNKNOWN", - "message": "string" - } - ] + "can_exchange_messages": true, + "client_errs": [["string"]], + "client_logs": [["string"]], + "error": "string", + "healthy": true, + "node": { + "canPort80": true, + "certName": "string", + "derpport": 0, + "forceHTTP": true, + "hostName": "string", + "insecureForTests": true, + "ipv4": "string", + "ipv6": "string", + "name": "string", + "regionID": 0, + "stunonly": true, + "stunport": 0, + "stuntestIP": "string" + }, + "node_info": { + "tokenBucketBytesBurst": 0, + "tokenBucketBytesPerSecond": 0 + }, + "round_trip_ping": "string", + "round_trip_ping_ms": 0, + "severity": "ok", + "stun": { + "canSTUN": true, + "enabled": true, + "error": "string" + }, + "uses_websocket": true, + "warnings": [ + { + "code": "EUNKNOWN", + "message": "string" + } + ] } ``` @@ -8084,82 +8084,82 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "error": "string", - "healthy": true, - "node_reports": [ - { - "can_exchange_messages": true, - "client_errs": [["string"]], - "client_logs": [["string"]], - "error": "string", - "healthy": true, - "node": { - "canPort80": true, - "certName": "string", - "derpport": 0, - "forceHTTP": true, - "hostName": "string", - "insecureForTests": true, - "ipv4": "string", - "ipv6": "string", - "name": "string", - "regionID": 0, - "stunonly": true, - "stunport": 0, - "stuntestIP": "string" - }, - "node_info": { - "tokenBucketBytesBurst": 0, - "tokenBucketBytesPerSecond": 0 - }, - "round_trip_ping": "string", - "round_trip_ping_ms": 0, - "severity": "ok", - "stun": { - "canSTUN": true, - "enabled": true, - "error": "string" - }, - "uses_websocket": true, - "warnings": [ - { - "code": "EUNKNOWN", - "message": "string" - } - ] - } - ], - "region": { - "avoid": true, - "embeddedRelay": true, - "nodes": [ - { - "canPort80": true, - "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" - }, - "severity": "ok", - "warnings": [ - { - "code": "EUNKNOWN", - "message": "string" - } - ] + "error": "string", + "healthy": true, + "node_reports": [ + { + "can_exchange_messages": true, + "client_errs": [["string"]], + "client_logs": [["string"]], + "error": "string", + "healthy": true, + "node": { + "canPort80": true, + "certName": "string", + "derpport": 0, + "forceHTTP": true, + "hostName": "string", + "insecureForTests": true, + "ipv4": "string", + "ipv6": "string", + "name": "string", + "regionID": 0, + "stunonly": true, + "stunport": 0, + "stuntestIP": "string" + }, + "node_info": { + "tokenBucketBytesBurst": 0, + "tokenBucketBytesPerSecond": 0 + }, + "round_trip_ping": "string", + "round_trip_ping_ms": 0, + "severity": "ok", + "stun": { + "canSTUN": true, + "enabled": true, + "error": "string" + }, + "uses_websocket": true, + "warnings": [ + { + "code": "EUNKNOWN", + "message": "string" + } + ] + } + ], + "region": { + "avoid": true, + "embeddedRelay": true, + "nodes": [ + { + "canPort80": true, + "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" + }, + "severity": "ok", + "warnings": [ + { + "code": "EUNKNOWN", + "message": "string" + } + ] } ``` @@ -8186,20 +8186,20 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "dismissed": true, - "error": "string", - "healthy": true, - "latency": "string", - "latency_ms": 0, - "reachable": true, - "severity": "ok", - "threshold_ms": 0, - "warnings": [ - { - "code": "EUNKNOWN", - "message": "string" - } - ] + "dismissed": true, + "error": "string", + "healthy": true, + "latency": "string", + "latency_ms": 0, + "reachable": true, + "severity": "ok", + "threshold_ms": 0, + "warnings": [ + { + "code": "EUNKNOWN", + "message": "string" + } + ] } ``` @@ -8248,7 +8248,7 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "dismissed_healthchecks": ["DERP"] + "dismissed_healthchecks": ["DERP"] } ``` @@ -8262,332 +8262,332 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "access_url": { - "access_url": "string", - "dismissed": true, - "error": "string", - "healthy": true, - "healthz_response": "string", - "reachable": true, - "severity": "ok", - "status_code": 0, - "warnings": [ - { - "code": "EUNKNOWN", - "message": "string" - } - ] - }, - "coder_version": "string", - "database": { - "dismissed": true, - "error": "string", - "healthy": true, - "latency": "string", - "latency_ms": 0, - "reachable": true, - "severity": "ok", - "threshold_ms": 0, - "warnings": [ - { - "code": "EUNKNOWN", - "message": "string" - } - ] - }, - "derp": { - "dismissed": true, - "error": "string", - "healthy": true, - "netcheck": { - "captivePortal": "string", - "globalV4": "string", - "globalV6": "string", - "hairPinning": "string", - "icmpv4": true, - "ipv4": true, - "ipv4CanSend": true, - "ipv6": true, - "ipv6CanSend": true, - "mappingVariesByDestIP": "string", - "oshasIPv6": true, - "pcp": "string", - "pmp": "string", - "preferredDERP": 0, - "regionLatency": { - "property1": 0, - "property2": 0 - }, - "regionV4Latency": { - "property1": 0, - "property2": 0 - }, - "regionV6Latency": { - "property1": 0, - "property2": 0 - }, - "udp": true, - "upnP": "string" - }, - "netcheck_err": "string", - "netcheck_logs": ["string"], - "regions": { - "property1": { - "error": "string", - "healthy": true, - "node_reports": [ - { - "can_exchange_messages": true, - "client_errs": [["string"]], - "client_logs": [["string"]], - "error": "string", - "healthy": true, - "node": { - "canPort80": true, - "certName": "string", - "derpport": 0, - "forceHTTP": true, - "hostName": "string", - "insecureForTests": true, - "ipv4": "string", - "ipv6": "string", - "name": "string", - "regionID": 0, - "stunonly": true, - "stunport": 0, - "stuntestIP": "string" - }, - "node_info": { - "tokenBucketBytesBurst": 0, - "tokenBucketBytesPerSecond": 0 - }, - "round_trip_ping": "string", - "round_trip_ping_ms": 0, - "severity": "ok", - "stun": { - "canSTUN": true, - "enabled": true, - "error": "string" - }, - "uses_websocket": true, - "warnings": [ - { - "code": "EUNKNOWN", - "message": "string" - } - ] - } - ], - "region": { - "avoid": true, - "embeddedRelay": true, - "nodes": [ - { - "canPort80": true, - "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" - }, - "severity": "ok", - "warnings": [ - { - "code": "EUNKNOWN", - "message": "string" - } - ] - }, - "property2": { - "error": "string", - "healthy": true, - "node_reports": [ - { - "can_exchange_messages": true, - "client_errs": [["string"]], - "client_logs": [["string"]], - "error": "string", - "healthy": true, - "node": { - "canPort80": true, - "certName": "string", - "derpport": 0, - "forceHTTP": true, - "hostName": "string", - "insecureForTests": true, - "ipv4": "string", - "ipv6": "string", - "name": "string", - "regionID": 0, - "stunonly": true, - "stunport": 0, - "stuntestIP": "string" - }, - "node_info": { - "tokenBucketBytesBurst": 0, - "tokenBucketBytesPerSecond": 0 - }, - "round_trip_ping": "string", - "round_trip_ping_ms": 0, - "severity": "ok", - "stun": { - "canSTUN": true, - "enabled": true, - "error": "string" - }, - "uses_websocket": true, - "warnings": [ - { - "code": "EUNKNOWN", - "message": "string" - } - ] - } - ], - "region": { - "avoid": true, - "embeddedRelay": true, - "nodes": [ - { - "canPort80": true, - "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" - }, - "severity": "ok", - "warnings": [ - { - "code": "EUNKNOWN", - "message": "string" - } - ] - } - }, - "severity": "ok", - "warnings": [ - { - "code": "EUNKNOWN", - "message": "string" - } - ] - }, - "healthy": true, - "provisioner_daemons": { - "dismissed": true, - "error": "string", - "items": [ - { - "provisioner_daemon": { - "api_version": "string", - "created_at": "2019-08-24T14:15:22Z", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "last_seen_at": "2019-08-24T14:15:22Z", - "name": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "provisioners": ["string"], - "tags": { - "property1": "string", - "property2": "string" - }, - "version": "string" - }, - "warnings": [ - { - "code": "EUNKNOWN", - "message": "string" - } - ] - } - ], - "severity": "ok", - "warnings": [ - { - "code": "EUNKNOWN", - "message": "string" - } - ] - }, - "severity": "ok", - "time": "2019-08-24T14:15:22Z", - "websocket": { - "body": "string", - "code": 0, - "dismissed": true, - "error": "string", - "healthy": true, - "severity": "ok", - "warnings": [ - { - "code": "EUNKNOWN", - "message": "string" - } - ] - }, - "workspace_proxy": { - "dismissed": true, - "error": "string", - "healthy": true, - "severity": "ok", - "warnings": [ - { - "code": "EUNKNOWN", - "message": "string" - } - ], - "workspace_proxies": { - "regions": [ - { - "created_at": "2019-08-24T14:15:22Z", - "deleted": true, - "derp_enabled": true, - "derp_only": true, - "display_name": "string", - "healthy": true, - "icon_url": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "name": "string", - "path_app_url": "string", - "status": { - "checked_at": "2019-08-24T14:15:22Z", - "report": { - "errors": ["string"], - "warnings": ["string"] - }, - "status": "ok" - }, - "updated_at": "2019-08-24T14:15:22Z", - "version": "string", - "wildcard_hostname": "string" - } - ] - } - } + "access_url": { + "access_url": "string", + "dismissed": true, + "error": "string", + "healthy": true, + "healthz_response": "string", + "reachable": true, + "severity": "ok", + "status_code": 0, + "warnings": [ + { + "code": "EUNKNOWN", + "message": "string" + } + ] + }, + "coder_version": "string", + "database": { + "dismissed": true, + "error": "string", + "healthy": true, + "latency": "string", + "latency_ms": 0, + "reachable": true, + "severity": "ok", + "threshold_ms": 0, + "warnings": [ + { + "code": "EUNKNOWN", + "message": "string" + } + ] + }, + "derp": { + "dismissed": true, + "error": "string", + "healthy": true, + "netcheck": { + "captivePortal": "string", + "globalV4": "string", + "globalV6": "string", + "hairPinning": "string", + "icmpv4": true, + "ipv4": true, + "ipv4CanSend": true, + "ipv6": true, + "ipv6CanSend": true, + "mappingVariesByDestIP": "string", + "oshasIPv6": true, + "pcp": "string", + "pmp": "string", + "preferredDERP": 0, + "regionLatency": { + "property1": 0, + "property2": 0 + }, + "regionV4Latency": { + "property1": 0, + "property2": 0 + }, + "regionV6Latency": { + "property1": 0, + "property2": 0 + }, + "udp": true, + "upnP": "string" + }, + "netcheck_err": "string", + "netcheck_logs": ["string"], + "regions": { + "property1": { + "error": "string", + "healthy": true, + "node_reports": [ + { + "can_exchange_messages": true, + "client_errs": [["string"]], + "client_logs": [["string"]], + "error": "string", + "healthy": true, + "node": { + "canPort80": true, + "certName": "string", + "derpport": 0, + "forceHTTP": true, + "hostName": "string", + "insecureForTests": true, + "ipv4": "string", + "ipv6": "string", + "name": "string", + "regionID": 0, + "stunonly": true, + "stunport": 0, + "stuntestIP": "string" + }, + "node_info": { + "tokenBucketBytesBurst": 0, + "tokenBucketBytesPerSecond": 0 + }, + "round_trip_ping": "string", + "round_trip_ping_ms": 0, + "severity": "ok", + "stun": { + "canSTUN": true, + "enabled": true, + "error": "string" + }, + "uses_websocket": true, + "warnings": [ + { + "code": "EUNKNOWN", + "message": "string" + } + ] + } + ], + "region": { + "avoid": true, + "embeddedRelay": true, + "nodes": [ + { + "canPort80": true, + "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" + }, + "severity": "ok", + "warnings": [ + { + "code": "EUNKNOWN", + "message": "string" + } + ] + }, + "property2": { + "error": "string", + "healthy": true, + "node_reports": [ + { + "can_exchange_messages": true, + "client_errs": [["string"]], + "client_logs": [["string"]], + "error": "string", + "healthy": true, + "node": { + "canPort80": true, + "certName": "string", + "derpport": 0, + "forceHTTP": true, + "hostName": "string", + "insecureForTests": true, + "ipv4": "string", + "ipv6": "string", + "name": "string", + "regionID": 0, + "stunonly": true, + "stunport": 0, + "stuntestIP": "string" + }, + "node_info": { + "tokenBucketBytesBurst": 0, + "tokenBucketBytesPerSecond": 0 + }, + "round_trip_ping": "string", + "round_trip_ping_ms": 0, + "severity": "ok", + "stun": { + "canSTUN": true, + "enabled": true, + "error": "string" + }, + "uses_websocket": true, + "warnings": [ + { + "code": "EUNKNOWN", + "message": "string" + } + ] + } + ], + "region": { + "avoid": true, + "embeddedRelay": true, + "nodes": [ + { + "canPort80": true, + "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" + }, + "severity": "ok", + "warnings": [ + { + "code": "EUNKNOWN", + "message": "string" + } + ] + } + }, + "severity": "ok", + "warnings": [ + { + "code": "EUNKNOWN", + "message": "string" + } + ] + }, + "healthy": true, + "provisioner_daemons": { + "dismissed": true, + "error": "string", + "items": [ + { + "provisioner_daemon": { + "api_version": "string", + "created_at": "2019-08-24T14:15:22Z", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "last_seen_at": "2019-08-24T14:15:22Z", + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "provisioners": ["string"], + "tags": { + "property1": "string", + "property2": "string" + }, + "version": "string" + }, + "warnings": [ + { + "code": "EUNKNOWN", + "message": "string" + } + ] + } + ], + "severity": "ok", + "warnings": [ + { + "code": "EUNKNOWN", + "message": "string" + } + ] + }, + "severity": "ok", + "time": "2019-08-24T14:15:22Z", + "websocket": { + "body": "string", + "code": 0, + "dismissed": true, + "error": "string", + "healthy": true, + "severity": "ok", + "warnings": [ + { + "code": "EUNKNOWN", + "message": "string" + } + ] + }, + "workspace_proxy": { + "dismissed": true, + "error": "string", + "healthy": true, + "severity": "ok", + "warnings": [ + { + "code": "EUNKNOWN", + "message": "string" + } + ], + "workspace_proxies": { + "regions": [ + { + "created_at": "2019-08-24T14:15:22Z", + "deleted": true, + "derp_enabled": true, + "derp_only": true, + "display_name": "string", + "healthy": true, + "icon_url": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "string", + "path_app_url": "string", + "status": { + "checked_at": "2019-08-24T14:15:22Z", + "report": { + "errors": ["string"], + "warnings": ["string"] + }, + "status": "ok" + }, + "updated_at": "2019-08-24T14:15:22Z", + "version": "string", + "wildcard_hostname": "string" + } + ] + } + } } ``` @@ -8618,39 +8618,39 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "dismissed": true, - "error": "string", - "items": [ - { - "provisioner_daemon": { - "api_version": "string", - "created_at": "2019-08-24T14:15:22Z", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "last_seen_at": "2019-08-24T14:15:22Z", - "name": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "provisioners": ["string"], - "tags": { - "property1": "string", - "property2": "string" - }, - "version": "string" - }, - "warnings": [ - { - "code": "EUNKNOWN", - "message": "string" - } - ] - } - ], - "severity": "ok", - "warnings": [ - { - "code": "EUNKNOWN", - "message": "string" - } - ] + "dismissed": true, + "error": "string", + "items": [ + { + "provisioner_daemon": { + "api_version": "string", + "created_at": "2019-08-24T14:15:22Z", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "last_seen_at": "2019-08-24T14:15:22Z", + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "provisioners": ["string"], + "tags": { + "property1": "string", + "property2": "string" + }, + "version": "string" + }, + "warnings": [ + { + "code": "EUNKNOWN", + "message": "string" + } + ] + } + ], + "severity": "ok", + "warnings": [ + { + "code": "EUNKNOWN", + "message": "string" + } + ] } ``` @@ -8676,26 +8676,26 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "provisioner_daemon": { - "api_version": "string", - "created_at": "2019-08-24T14:15:22Z", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "last_seen_at": "2019-08-24T14:15:22Z", - "name": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "provisioners": ["string"], - "tags": { - "property1": "string", - "property2": "string" - }, - "version": "string" - }, - "warnings": [ - { - "code": "EUNKNOWN", - "message": "string" - } - ] + "provisioner_daemon": { + "api_version": "string", + "created_at": "2019-08-24T14:15:22Z", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "last_seen_at": "2019-08-24T14:15:22Z", + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "provisioners": ["string"], + "tags": { + "property1": "string", + "property2": "string" + }, + "version": "string" + }, + "warnings": [ + { + "code": "EUNKNOWN", + "message": "string" + } + ] } ``` @@ -8710,9 +8710,9 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "canSTUN": true, - "enabled": true, - "error": "string" + "canSTUN": true, + "enabled": true, + "error": "string" } ``` @@ -8728,7 +8728,7 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "dismissed_healthchecks": ["DERP"] + "dismissed_healthchecks": ["DERP"] } ``` @@ -8742,18 +8742,18 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "body": "string", - "code": 0, - "dismissed": true, - "error": "string", - "healthy": true, - "severity": "ok", - "warnings": [ - { - "code": "EUNKNOWN", - "message": "string" - } - ] + "body": "string", + "code": 0, + "dismissed": true, + "error": "string", + "healthy": true, + "severity": "ok", + "warnings": [ + { + "code": "EUNKNOWN", + "message": "string" + } + ] } ``` @@ -8781,43 +8781,43 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { - "dismissed": true, - "error": "string", - "healthy": true, - "severity": "ok", - "warnings": [ - { - "code": "EUNKNOWN", - "message": "string" - } - ], - "workspace_proxies": { - "regions": [ - { - "created_at": "2019-08-24T14:15:22Z", - "deleted": true, - "derp_enabled": true, - "derp_only": true, - "display_name": "string", - "healthy": true, - "icon_url": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "name": "string", - "path_app_url": "string", - "status": { - "checked_at": "2019-08-24T14:15:22Z", - "report": { - "errors": ["string"], - "warnings": ["string"] - }, - "status": "ok" - }, - "updated_at": "2019-08-24T14:15:22Z", - "version": "string", - "wildcard_hostname": "string" - } - ] - } + "dismissed": true, + "error": "string", + "healthy": true, + "severity": "ok", + "warnings": [ + { + "code": "EUNKNOWN", + "message": "string" + } + ], + "workspace_proxies": { + "regions": [ + { + "created_at": "2019-08-24T14:15:22Z", + "deleted": true, + "derp_enabled": true, + "derp_only": true, + "display_name": "string", + "healthy": true, + "icon_url": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "string", + "path_app_url": "string", + "status": { + "checked_at": "2019-08-24T14:15:22Z", + "report": { + "errors": ["string"], + "warnings": ["string"] + }, + "status": "ok" + }, + "updated_at": "2019-08-24T14:15:22Z", + "version": "string", + "wildcard_hostname": "string" + } + ] + } } ``` @@ -8854,34 +8854,34 @@ _None_ ```json { - "captivePortal": "string", - "globalV4": "string", - "globalV6": "string", - "hairPinning": "string", - "icmpv4": true, - "ipv4": true, - "ipv4CanSend": true, - "ipv6": true, - "ipv6CanSend": true, - "mappingVariesByDestIP": "string", - "oshasIPv6": true, - "pcp": "string", - "pmp": "string", - "preferredDERP": 0, - "regionLatency": { - "property1": 0, - "property2": 0 - }, - "regionV4Latency": { - "property1": 0, - "property2": 0 - }, - "regionV6Latency": { - "property1": 0, - "property2": 0 - }, - "udp": true, - "upnP": "string" + "captivePortal": "string", + "globalV4": "string", + "globalV6": "string", + "hairPinning": "string", + "icmpv4": true, + "ipv4": true, + "ipv4CanSend": true, + "ipv6": true, + "ipv6CanSend": true, + "mappingVariesByDestIP": "string", + "oshasIPv6": true, + "pcp": "string", + "pmp": "string", + "preferredDERP": 0, + "regionLatency": { + "property1": 0, + "property2": 0 + }, + "regionV4Latency": { + "property1": 0, + "property2": 0 + }, + "regionV6Latency": { + "property1": 0, + "property2": 0 + }, + "udp": true, + "upnP": "string" } ``` @@ -8916,10 +8916,10 @@ _None_ ```json { - "access_token": "string", - "expiry": "string", - "refresh_token": "string", - "token_type": "string" + "access_token": "string", + "expiry": "string", + "refresh_token": "string", + "token_type": "string" } ``` @@ -8937,8 +8937,8 @@ _None_ ```json { - "property1": "string", - "property2": "string" + "property1": "string", + "property2": "string" } ``` @@ -8952,15 +8952,15 @@ _None_ ```json { - "description": "string", - "name": "string", - "parent": { - "description": "string", - "name": "string", - "parent": {}, - "yaml": "string" - }, - "yaml": "string" + "description": "string", + "name": "string", + "parent": { + "description": "string", + "name": "string", + "parent": {}, + "yaml": "string" + }, + "yaml": "string" } ``` @@ -8977,8 +8977,8 @@ _None_ ```json { - "host": "string", - "port": "string" + "host": "string", + "port": "string" } ``` @@ -8993,63 +8993,63 @@ _None_ ```json { - "annotations": { - "property1": "string", - "property2": "string" - }, - "default": "string", - "description": "string", - "env": "string", - "flag": "string", - "flag_shorthand": "string", - "group": { - "description": "string", - "name": "string", - "parent": { - "description": "string", - "name": "string", - "parent": {}, - "yaml": "string" - }, - "yaml": "string" - }, - "hidden": true, - "name": "string", - "required": true, - "use_instead": [ - { - "annotations": { - "property1": "string", - "property2": "string" - }, - "default": "string", - "description": "string", - "env": "string", - "flag": "string", - "flag_shorthand": "string", - "group": { - "description": "string", - "name": "string", - "parent": { - "description": "string", - "name": "string", - "parent": {}, - "yaml": "string" - }, - "yaml": "string" - }, - "hidden": true, - "name": "string", - "required": true, - "use_instead": [], - "value": null, - "value_source": "", - "yaml": "string" - } - ], - "value": null, - "value_source": "", - "yaml": "string" + "annotations": { + "property1": "string", + "property2": "string" + }, + "default": "string", + "description": "string", + "env": "string", + "flag": "string", + "flag_shorthand": "string", + "group": { + "description": "string", + "name": "string", + "parent": { + "description": "string", + "name": "string", + "parent": {}, + "yaml": "string" + }, + "yaml": "string" + }, + "hidden": true, + "name": "string", + "required": true, + "use_instead": [ + { + "annotations": { + "property1": "string", + "property2": "string" + }, + "default": "string", + "description": "string", + "env": "string", + "flag": "string", + "flag_shorthand": "string", + "group": { + "description": "string", + "name": "string", + "parent": { + "description": "string", + "name": "string", + "parent": {}, + "yaml": "string" + }, + "yaml": "string" + }, + "hidden": true, + "name": "string", + "required": true, + "use_instead": [], + "value": null, + "value_source": "", + "yaml": "string" + } + ], + "value": null, + "value_source": "", + "yaml": "string" } ``` @@ -9086,25 +9086,25 @@ _None_ ```json { - "value": [ - { - "app_install_url": "string", - "app_installations_url": "string", - "auth_url": "string", - "client_id": "string", - "device_code_url": "string", - "device_flow": true, - "display_icon": "string", - "display_name": "string", - "id": "string", - "no_refresh": true, - "regex": "string", - "scopes": ["string"], - "token_url": "string", - "type": "string", - "validate_url": "string" - } - ] + "value": [ + { + "app_install_url": "string", + "app_installations_url": "string", + "auth_url": "string", + "client_id": "string", + "device_code_url": "string", + "device_flow": true, + "display_icon": "string", + "display_name": "string", + "id": "string", + "no_refresh": true, + "regex": "string", + "scopes": ["string"], + "token_url": "string", + "type": "string", + "validate_url": "string" + } + ] } ``` @@ -9118,13 +9118,13 @@ _None_ ```json { - "value": [ - { - "icon": "bug", - "name": "string", - "target": "string" - } - ] + "value": [ + { + "icon": "bug", + "name": "string", + "target": "string" + } + ] } ``` @@ -9138,17 +9138,17 @@ _None_ ```json { - "forceQuery": true, - "fragment": "string", - "host": "string", - "omitHost": true, - "opaque": "string", - "path": "string", - "rawFragment": "string", - "rawPath": "string", - "rawQuery": "string", - "scheme": "string", - "user": {} + "forceQuery": true, + "fragment": "string", + "host": "string", + "omitHost": true, + "opaque": "string", + "path": "string", + "rawFragment": "string", + "rawPath": "string", + "rawQuery": "string", + "scheme": "string", + "user": {} } ``` @@ -9190,10 +9190,10 @@ _None_ ```json { - "regionScore": { - "property1": 0, - "property2": 0 - } + "regionScore": { + "property1": 0, + "property2": 0 + } } ``` @@ -9212,63 +9212,63 @@ A nil map means no change from the previous value (if any); an empty non-nil map ```json { - "homeParams": { - "regionScore": { - "property1": 0, - "property2": 0 - } - }, - "omitDefaultRegions": true, - "regions": { - "property1": { - "avoid": true, - "embeddedRelay": true, - "nodes": [ - { - "canPort80": true, - "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": [ - { - "canPort80": true, - "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" - } - } + "homeParams": { + "regionScore": { + "property1": 0, + "property2": 0 + } + }, + "omitDefaultRegions": true, + "regions": { + "property1": { + "avoid": true, + "embeddedRelay": true, + "nodes": [ + { + "canPort80": true, + "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": [ + { + "canPort80": true, + "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" + } + } } ``` @@ -9290,19 +9290,19 @@ The numbers are not necessarily contiguous.| ```json { - "canPort80": true, - "certName": "string", - "derpport": 0, - "forceHTTP": true, - "hostName": "string", - "insecureForTests": true, - "ipv4": "string", - "ipv6": "string", - "name": "string", - "regionID": 0, - "stunonly": true, - "stunport": 0, - "stuntestIP": "string" + "canPort80": true, + "certName": "string", + "derpport": 0, + "forceHTTP": true, + "hostName": "string", + "insecureForTests": true, + "ipv4": "string", + "ipv6": "string", + "name": "string", + "regionID": 0, + "stunonly": true, + "stunport": 0, + "stuntestIP": "string" } ``` @@ -9330,28 +9330,28 @@ The numbers are not necessarily contiguous.| ```json { - "avoid": true, - "embeddedRelay": true, - "nodes": [ - { - "canPort80": true, - "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" + "avoid": true, + "embeddedRelay": true, + "nodes": [ + { + "canPort80": true, + "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" } ``` @@ -9401,20 +9401,20 @@ _None_ ```json { - "app_hostname": "string", - "app_path": "string", - "app_query": "string", - "app_request": { - "access_method": "path", - "agent_name_or_id": "string", - "app_prefix": "string", - "app_slug_or_port": "string", - "base_path": "string", - "username_or_id": "string", - "workspace_name_or_id": "string" - }, - "path_app_base_url": "string", - "session_token": "string" + "app_hostname": "string", + "app_path": "string", + "app_query": "string", + "app_request": { + "access_method": "path", + "agent_name_or_id": "string", + "app_prefix": "string", + "app_slug_or_port": "string", + "base_path": "string", + "username_or_id": "string", + "workspace_name_or_id": "string" + }, + "path_app_base_url": "string", + "session_token": "string" } ``` @@ -9433,13 +9433,13 @@ _None_ ```json { - "access_method": "path", - "agent_name_or_id": "string", - "app_prefix": "string", - "app_slug_or_port": "string", - "base_path": "string", - "username_or_id": "string", - "workspace_name_or_id": "string" + "access_method": "path", + "agent_name_or_id": "string", + "app_prefix": "string", + "app_slug_or_port": "string", + "base_path": "string", + "username_or_id": "string", + "workspace_name_or_id": "string" } ``` @@ -9459,15 +9459,15 @@ _None_ ```json { - "access_method": "path", - "agent_id": "string", - "requests": 0, - "session_ended_at": "string", - "session_id": "string", - "session_started_at": "string", - "slug_or_port": "string", - "user_id": "string", - "workspace_id": "string" + "access_method": "path", + "agent_id": "string", + "requests": 0, + "session_ended_at": "string", + "session_id": "string", + "session_started_at": "string", + "slug_or_port": "string", + "user_id": "string", + "workspace_id": "string" } ``` @@ -9489,67 +9489,67 @@ _None_ ```json { - "derp_force_websockets": true, - "derp_map": { - "homeParams": { - "regionScore": { - "property1": 0, - "property2": 0 - } - }, - "omitDefaultRegions": true, - "regions": { - "property1": { - "avoid": true, - "embeddedRelay": true, - "nodes": [ - { - "canPort80": true, - "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": [ - { - "canPort80": true, - "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" - } - } - }, - "disable_direct_connections": true + "derp_force_websockets": true, + "derp_map": { + "homeParams": { + "regionScore": { + "property1": 0, + "property2": 0 + } + }, + "omitDefaultRegions": true, + "regions": { + "property1": { + "avoid": true, + "embeddedRelay": true, + "nodes": [ + { + "canPort80": true, + "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": [ + { + "canPort80": true, + "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" + } + } + }, + "disable_direct_connections": true } ``` @@ -9565,7 +9565,7 @@ _None_ ```json { - "replica_id": "string" + "replica_id": "string" } ``` @@ -9579,7 +9579,7 @@ _None_ ```json { - "signed_token_str": "string" + "signed_token_str": "string" } ``` @@ -9593,15 +9593,15 @@ _None_ ```json { - "access_url": "string", - "derp_enabled": true, - "derp_only": true, - "hostname": "string", - "replica_error": "string", - "replica_id": "string", - "replica_relay_address": "string", - "version": "string", - "wildcard_hostname": "string" + "access_url": "string", + "derp_enabled": true, + "derp_only": true, + "hostname": "string", + "replica_error": "string", + "replica_id": "string", + "replica_relay_address": "string", + "version": "string", + "wildcard_hostname": "string" } ``` @@ -9624,80 +9624,80 @@ _None_ ```json { - "app_security_key": "string", - "derp_force_websockets": true, - "derp_map": { - "homeParams": { - "regionScore": { - "property1": 0, - "property2": 0 - } - }, - "omitDefaultRegions": true, - "regions": { - "property1": { - "avoid": true, - "embeddedRelay": true, - "nodes": [ - { - "canPort80": true, - "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": [ - { - "canPort80": true, - "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" - } - } - }, - "derp_mesh_key": "string", - "derp_region_id": 0, - "sibling_replicas": [ - { - "created_at": "2019-08-24T14:15:22Z", - "database_latency": 0, - "error": "string", - "hostname": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "region_id": 0, - "relay_address": "string" - } - ] + "app_security_key": "string", + "derp_force_websockets": true, + "derp_map": { + "homeParams": { + "regionScore": { + "property1": 0, + "property2": 0 + } + }, + "omitDefaultRegions": true, + "regions": { + "property1": { + "avoid": true, + "embeddedRelay": true, + "nodes": [ + { + "canPort80": true, + "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": [ + { + "canPort80": true, + "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" + } + } + }, + "derp_mesh_key": "string", + "derp_region_id": 0, + "sibling_replicas": [ + { + "created_at": "2019-08-24T14:15:22Z", + "database_latency": 0, + "error": "string", + "hostname": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "region_id": 0, + "relay_address": "string" + } + ] } ``` @@ -9716,19 +9716,19 @@ _None_ ```json { - "stats": [ - { - "access_method": "path", - "agent_id": "string", - "requests": 0, - "session_ended_at": "string", - "session_id": "string", - "session_started_at": "string", - "slug_or_port": "string", - "user_id": "string", - "workspace_id": "string" - } - ] + "stats": [ + { + "access_method": "path", + "agent_id": "string", + "requests": 0, + "session_ended_at": "string", + "session_id": "string", + "session_started_at": "string", + "slug_or_port": "string", + "user_id": "string", + "workspace_id": "string" + } + ] } ``` diff --git a/docs/reference/api/templates.md b/docs/reference/api/templates.md index 1a47cb6000..da7b61d8a2 100644 --- a/docs/reference/api/templates.md +++ b/docs/reference/api/templates.md @@ -25,53 +25,53 @@ curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/templat ```json [ - { - "active_user_count": 0, - "active_version_id": "eae64611-bd53-4a80-bb77-df1e432c0fbc", - "activity_bump_ms": 0, - "allow_user_autostart": true, - "allow_user_autostop": true, - "allow_user_cancel_workspace_jobs": true, - "autostart_requirement": { - "days_of_week": ["monday"] - }, - "autostop_requirement": { - "days_of_week": ["monday"], - "weeks": 0 - }, - "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, - "deprecated": true, - "deprecation_message": "string", - "description": "string", - "display_name": "string", - "failure_ttl_ms": 0, - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "max_port_share_level": "owner", - "name": "string", - "organization_display_name": "string", - "organization_icon": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "organization_name": "string", - "provisioner": "terraform", - "require_active_version": true, - "time_til_dormant_autodelete_ms": 0, - "time_til_dormant_ms": 0, - "updated_at": "2019-08-24T14:15:22Z" - } + { + "active_user_count": 0, + "active_version_id": "eae64611-bd53-4a80-bb77-df1e432c0fbc", + "activity_bump_ms": 0, + "allow_user_autostart": true, + "allow_user_autostop": true, + "allow_user_cancel_workspace_jobs": true, + "autostart_requirement": { + "days_of_week": ["monday"] + }, + "autostop_requirement": { + "days_of_week": ["monday"], + "weeks": 0 + }, + "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, + "deprecated": true, + "deprecation_message": "string", + "description": "string", + "display_name": "string", + "failure_ttl_ms": 0, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "max_port_share_level": "owner", + "name": "string", + "organization_display_name": "string", + "organization_icon": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "organization_name": "string", + "provisioner": "terraform", + "require_active_version": true, + "time_til_dormant_autodelete_ms": 0, + "time_til_dormant_ms": 0, + "updated_at": "2019-08-24T14:15:22Z" + } ] ``` @@ -156,28 +156,28 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/templa ```json { - "activity_bump_ms": 0, - "allow_user_autostart": true, - "allow_user_autostop": true, - "allow_user_cancel_workspace_jobs": true, - "autostart_requirement": { - "days_of_week": ["monday"] - }, - "autostop_requirement": { - "days_of_week": ["monday"], - "weeks": 0 - }, - "default_ttl_ms": 0, - "delete_ttl_ms": 0, - "description": "string", - "disable_everyone_group_access": true, - "display_name": "string", - "dormant_ttl_ms": 0, - "failure_ttl_ms": 0, - "icon": "string", - "name": "string", - "require_active_version": true, - "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1" + "activity_bump_ms": 0, + "allow_user_autostart": true, + "allow_user_autostop": true, + "allow_user_cancel_workspace_jobs": true, + "autostart_requirement": { + "days_of_week": ["monday"] + }, + "autostop_requirement": { + "days_of_week": ["monday"], + "weeks": 0 + }, + "default_ttl_ms": 0, + "delete_ttl_ms": 0, + "description": "string", + "disable_everyone_group_access": true, + "display_name": "string", + "dormant_ttl_ms": 0, + "failure_ttl_ms": 0, + "icon": "string", + "name": "string", + "require_active_version": true, + "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1" } ``` @@ -194,51 +194,51 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/templa ```json { - "active_user_count": 0, - "active_version_id": "eae64611-bd53-4a80-bb77-df1e432c0fbc", - "activity_bump_ms": 0, - "allow_user_autostart": true, - "allow_user_autostop": true, - "allow_user_cancel_workspace_jobs": true, - "autostart_requirement": { - "days_of_week": ["monday"] - }, - "autostop_requirement": { - "days_of_week": ["monday"], - "weeks": 0 - }, - "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, - "deprecated": true, - "deprecation_message": "string", - "description": "string", - "display_name": "string", - "failure_ttl_ms": 0, - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "max_port_share_level": "owner", - "name": "string", - "organization_display_name": "string", - "organization_icon": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "organization_name": "string", - "provisioner": "terraform", - "require_active_version": true, - "time_til_dormant_autodelete_ms": 0, - "time_til_dormant_ms": 0, - "updated_at": "2019-08-24T14:15:22Z" + "active_user_count": 0, + "active_version_id": "eae64611-bd53-4a80-bb77-df1e432c0fbc", + "activity_bump_ms": 0, + "allow_user_autostart": true, + "allow_user_autostop": true, + "allow_user_cancel_workspace_jobs": true, + "autostart_requirement": { + "days_of_week": ["monday"] + }, + "autostop_requirement": { + "days_of_week": ["monday"], + "weeks": 0 + }, + "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, + "deprecated": true, + "deprecation_message": "string", + "description": "string", + "display_name": "string", + "failure_ttl_ms": 0, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "max_port_share_level": "owner", + "name": "string", + "organization_display_name": "string", + "organization_icon": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "organization_name": "string", + "provisioner": "terraform", + "require_active_version": true, + "time_til_dormant_autodelete_ms": 0, + "time_til_dormant_ms": 0, + "updated_at": "2019-08-24T14:15:22Z" } ``` @@ -275,15 +275,15 @@ curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/templat ```json [ - { - "description": "string", - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "markdown": "string", - "name": "string", - "tags": ["string"], - "url": "string" - } + { + "description": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "markdown": "string", + "name": "string", + "tags": ["string"], + "url": "string" + } ] ``` @@ -336,51 +336,51 @@ curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/templat ```json { - "active_user_count": 0, - "active_version_id": "eae64611-bd53-4a80-bb77-df1e432c0fbc", - "activity_bump_ms": 0, - "allow_user_autostart": true, - "allow_user_autostop": true, - "allow_user_cancel_workspace_jobs": true, - "autostart_requirement": { - "days_of_week": ["monday"] - }, - "autostop_requirement": { - "days_of_week": ["monday"], - "weeks": 0 - }, - "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, - "deprecated": true, - "deprecation_message": "string", - "description": "string", - "display_name": "string", - "failure_ttl_ms": 0, - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "max_port_share_level": "owner", - "name": "string", - "organization_display_name": "string", - "organization_icon": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "organization_name": "string", - "provisioner": "terraform", - "require_active_version": true, - "time_til_dormant_autodelete_ms": 0, - "time_til_dormant_ms": 0, - "updated_at": "2019-08-24T14:15:22Z" + "active_user_count": 0, + "active_version_id": "eae64611-bd53-4a80-bb77-df1e432c0fbc", + "activity_bump_ms": 0, + "allow_user_autostart": true, + "allow_user_autostop": true, + "allow_user_cancel_workspace_jobs": true, + "autostart_requirement": { + "days_of_week": ["monday"] + }, + "autostop_requirement": { + "days_of_week": ["monday"], + "weeks": 0 + }, + "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, + "deprecated": true, + "deprecation_message": "string", + "description": "string", + "display_name": "string", + "failure_ttl_ms": 0, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "max_port_share_level": "owner", + "name": "string", + "organization_display_name": "string", + "organization_icon": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "organization_name": "string", + "provisioner": "terraform", + "require_active_version": true, + "time_til_dormant_autodelete_ms": 0, + "time_til_dormant_ms": 0, + "updated_at": "2019-08-24T14:15:22Z" } ``` @@ -419,39 +419,39 @@ curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/templat ```json { - "archived": true, - "created_at": "2019-08-24T14:15:22Z", - "created_by": { - "avatar_url": "http://example.com", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "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", - "error_code": "REQUIRED_TEMPLATE_VARIABLES", - "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "queue_position": 0, - "queue_size": 0, - "started_at": "2019-08-24T14:15:22Z", - "status": "pending", - "tags": { - "property1": "string", - "property2": "string" - }, - "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" - }, - "message": "string", - "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", - "warnings": ["UNSUPPORTED_WORKSPACES"] + "archived": true, + "created_at": "2019-08-24T14:15:22Z", + "created_by": { + "avatar_url": "http://example.com", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "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", + "error_code": "REQUIRED_TEMPLATE_VARIABLES", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "queue_position": 0, + "queue_size": 0, + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" + }, + "message": "string", + "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", + "warnings": ["UNSUPPORTED_WORKSPACES"] } ``` @@ -490,39 +490,39 @@ curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/templat ```json { - "archived": true, - "created_at": "2019-08-24T14:15:22Z", - "created_by": { - "avatar_url": "http://example.com", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "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", - "error_code": "REQUIRED_TEMPLATE_VARIABLES", - "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "queue_position": 0, - "queue_size": 0, - "started_at": "2019-08-24T14:15:22Z", - "status": "pending", - "tags": { - "property1": "string", - "property2": "string" - }, - "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" - }, - "message": "string", - "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", - "warnings": ["UNSUPPORTED_WORKSPACES"] + "archived": true, + "created_at": "2019-08-24T14:15:22Z", + "created_by": { + "avatar_url": "http://example.com", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "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", + "error_code": "REQUIRED_TEMPLATE_VARIABLES", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "queue_position": 0, + "queue_size": 0, + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" + }, + "message": "string", + "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", + "warnings": ["UNSUPPORTED_WORKSPACES"] } ``` @@ -552,23 +552,23 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/templa ```json { - "example_id": "string", - "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", - "message": "string", - "name": "string", - "provisioner": "terraform", - "storage_method": "file", - "tags": { - "property1": "string", - "property2": "string" - }, - "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", - "user_variable_values": [ - { - "name": "string", - "value": "string" - } - ] + "example_id": "string", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "message": "string", + "name": "string", + "provisioner": "terraform", + "storage_method": "file", + "tags": { + "property1": "string", + "property2": "string" + }, + "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", + "user_variable_values": [ + { + "name": "string", + "value": "string" + } + ] } ``` @@ -585,39 +585,39 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/templa ```json { - "archived": true, - "created_at": "2019-08-24T14:15:22Z", - "created_by": { - "avatar_url": "http://example.com", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "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", - "error_code": "REQUIRED_TEMPLATE_VARIABLES", - "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "queue_position": 0, - "queue_size": 0, - "started_at": "2019-08-24T14:15:22Z", - "status": "pending", - "tags": { - "property1": "string", - "property2": "string" - }, - "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" - }, - "message": "string", - "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", - "warnings": ["UNSUPPORTED_WORKSPACES"] + "archived": true, + "created_at": "2019-08-24T14:15:22Z", + "created_by": { + "avatar_url": "http://example.com", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "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", + "error_code": "REQUIRED_TEMPLATE_VARIABLES", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "queue_position": 0, + "queue_size": 0, + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" + }, + "message": "string", + "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", + "warnings": ["UNSUPPORTED_WORKSPACES"] } ``` @@ -648,53 +648,53 @@ curl -X GET http://coder-server:8080/api/v2/templates \ ```json [ - { - "active_user_count": 0, - "active_version_id": "eae64611-bd53-4a80-bb77-df1e432c0fbc", - "activity_bump_ms": 0, - "allow_user_autostart": true, - "allow_user_autostop": true, - "allow_user_cancel_workspace_jobs": true, - "autostart_requirement": { - "days_of_week": ["monday"] - }, - "autostop_requirement": { - "days_of_week": ["monday"], - "weeks": 0 - }, - "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, - "deprecated": true, - "deprecation_message": "string", - "description": "string", - "display_name": "string", - "failure_ttl_ms": 0, - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "max_port_share_level": "owner", - "name": "string", - "organization_display_name": "string", - "organization_icon": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "organization_name": "string", - "provisioner": "terraform", - "require_active_version": true, - "time_til_dormant_autodelete_ms": 0, - "time_til_dormant_ms": 0, - "updated_at": "2019-08-24T14:15:22Z" - } + { + "active_user_count": 0, + "active_version_id": "eae64611-bd53-4a80-bb77-df1e432c0fbc", + "activity_bump_ms": 0, + "allow_user_autostart": true, + "allow_user_autostop": true, + "allow_user_cancel_workspace_jobs": true, + "autostart_requirement": { + "days_of_week": ["monday"] + }, + "autostop_requirement": { + "days_of_week": ["monday"], + "weeks": 0 + }, + "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, + "deprecated": true, + "deprecation_message": "string", + "description": "string", + "display_name": "string", + "failure_ttl_ms": 0, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "max_port_share_level": "owner", + "name": "string", + "organization_display_name": "string", + "organization_icon": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "organization_name": "string", + "provisioner": "terraform", + "require_active_version": true, + "time_til_dormant_autodelete_ms": 0, + "time_til_dormant_ms": 0, + "updated_at": "2019-08-24T14:15:22Z" + } ] ``` @@ -780,15 +780,15 @@ curl -X GET http://coder-server:8080/api/v2/templates/examples \ ```json [ - { - "description": "string", - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "markdown": "string", - "name": "string", - "tags": ["string"], - "url": "string" - } + { + "description": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "markdown": "string", + "name": "string", + "tags": ["string"], + "url": "string" + } ] ``` @@ -840,51 +840,51 @@ curl -X GET http://coder-server:8080/api/v2/templates/{template} \ ```json { - "active_user_count": 0, - "active_version_id": "eae64611-bd53-4a80-bb77-df1e432c0fbc", - "activity_bump_ms": 0, - "allow_user_autostart": true, - "allow_user_autostop": true, - "allow_user_cancel_workspace_jobs": true, - "autostart_requirement": { - "days_of_week": ["monday"] - }, - "autostop_requirement": { - "days_of_week": ["monday"], - "weeks": 0 - }, - "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, - "deprecated": true, - "deprecation_message": "string", - "description": "string", - "display_name": "string", - "failure_ttl_ms": 0, - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "max_port_share_level": "owner", - "name": "string", - "organization_display_name": "string", - "organization_icon": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "organization_name": "string", - "provisioner": "terraform", - "require_active_version": true, - "time_til_dormant_autodelete_ms": 0, - "time_til_dormant_ms": 0, - "updated_at": "2019-08-24T14:15:22Z" + "active_user_count": 0, + "active_version_id": "eae64611-bd53-4a80-bb77-df1e432c0fbc", + "activity_bump_ms": 0, + "allow_user_autostart": true, + "allow_user_autostop": true, + "allow_user_cancel_workspace_jobs": true, + "autostart_requirement": { + "days_of_week": ["monday"] + }, + "autostop_requirement": { + "days_of_week": ["monday"], + "weeks": 0 + }, + "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, + "deprecated": true, + "deprecation_message": "string", + "description": "string", + "display_name": "string", + "failure_ttl_ms": 0, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "max_port_share_level": "owner", + "name": "string", + "organization_display_name": "string", + "organization_icon": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "organization_name": "string", + "provisioner": "terraform", + "require_active_version": true, + "time_til_dormant_autodelete_ms": 0, + "time_til_dormant_ms": 0, + "updated_at": "2019-08-24T14:15:22Z" } ``` @@ -921,14 +921,14 @@ curl -X DELETE http://coder-server:8080/api/v2/templates/{template} \ ```json { - "detail": "string", - "message": "string", - "validations": [ - { - "detail": "string", - "field": "string" - } - ] + "detail": "string", + "message": "string", + "validations": [ + { + "detail": "string", + "field": "string" + } + ] } ``` @@ -965,51 +965,51 @@ curl -X PATCH http://coder-server:8080/api/v2/templates/{template} \ ```json { - "active_user_count": 0, - "active_version_id": "eae64611-bd53-4a80-bb77-df1e432c0fbc", - "activity_bump_ms": 0, - "allow_user_autostart": true, - "allow_user_autostop": true, - "allow_user_cancel_workspace_jobs": true, - "autostart_requirement": { - "days_of_week": ["monday"] - }, - "autostop_requirement": { - "days_of_week": ["monday"], - "weeks": 0 - }, - "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, - "deprecated": true, - "deprecation_message": "string", - "description": "string", - "display_name": "string", - "failure_ttl_ms": 0, - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "max_port_share_level": "owner", - "name": "string", - "organization_display_name": "string", - "organization_icon": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "organization_name": "string", - "provisioner": "terraform", - "require_active_version": true, - "time_til_dormant_autodelete_ms": 0, - "time_til_dormant_ms": 0, - "updated_at": "2019-08-24T14:15:22Z" + "active_user_count": 0, + "active_version_id": "eae64611-bd53-4a80-bb77-df1e432c0fbc", + "activity_bump_ms": 0, + "allow_user_autostart": true, + "allow_user_autostop": true, + "allow_user_cancel_workspace_jobs": true, + "autostart_requirement": { + "days_of_week": ["monday"] + }, + "autostop_requirement": { + "days_of_week": ["monday"], + "weeks": 0 + }, + "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, + "deprecated": true, + "deprecation_message": "string", + "description": "string", + "display_name": "string", + "failure_ttl_ms": 0, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "max_port_share_level": "owner", + "name": "string", + "organization_display_name": "string", + "organization_icon": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "organization_name": "string", + "provisioner": "terraform", + "require_active_version": true, + "time_til_dormant_autodelete_ms": 0, + "time_til_dormant_ms": 0, + "updated_at": "2019-08-24T14:15:22Z" } ``` @@ -1046,13 +1046,13 @@ curl -X GET http://coder-server:8080/api/v2/templates/{template}/daus \ ```json { - "entries": [ - { - "amount": 0, - "date": "string" - } - ], - "tz_hour_offset": 0 + "entries": [ + { + "amount": 0, + "date": "string" + } + ], + "tz_hour_offset": 0 } ``` @@ -1093,41 +1093,41 @@ curl -X GET http://coder-server:8080/api/v2/templates/{template}/versions \ ```json [ - { - "archived": true, - "created_at": "2019-08-24T14:15:22Z", - "created_by": { - "avatar_url": "http://example.com", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "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", - "error_code": "REQUIRED_TEMPLATE_VARIABLES", - "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "queue_position": 0, - "queue_size": 0, - "started_at": "2019-08-24T14:15:22Z", - "status": "pending", - "tags": { - "property1": "string", - "property2": "string" - }, - "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" - }, - "message": "string", - "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", - "warnings": ["UNSUPPORTED_WORKSPACES"] - } + { + "archived": true, + "created_at": "2019-08-24T14:15:22Z", + "created_by": { + "avatar_url": "http://example.com", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "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", + "error_code": "REQUIRED_TEMPLATE_VARIABLES", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "queue_position": 0, + "queue_size": 0, + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" + }, + "message": "string", + "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", + "warnings": ["UNSUPPORTED_WORKSPACES"] + } ] ``` @@ -1206,7 +1206,7 @@ curl -X PATCH http://coder-server:8080/api/v2/templates/{template}/versions \ ```json { - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08" + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08" } ``` @@ -1223,14 +1223,14 @@ curl -X PATCH http://coder-server:8080/api/v2/templates/{template}/versions \ ```json { - "detail": "string", - "message": "string", - "validations": [ - { - "detail": "string", - "field": "string" - } - ] + "detail": "string", + "message": "string", + "validations": [ + { + "detail": "string", + "field": "string" + } + ] } ``` @@ -1260,7 +1260,7 @@ curl -X POST http://coder-server:8080/api/v2/templates/{template}/versions/archi ```json { - "all": true + "all": true } ``` @@ -1277,14 +1277,14 @@ curl -X POST http://coder-server:8080/api/v2/templates/{template}/versions/archi ```json { - "detail": "string", - "message": "string", - "validations": [ - { - "detail": "string", - "field": "string" - } - ] + "detail": "string", + "message": "string", + "validations": [ + { + "detail": "string", + "field": "string" + } + ] } ``` @@ -1322,41 +1322,41 @@ curl -X GET http://coder-server:8080/api/v2/templates/{template}/versions/{templ ```json [ - { - "archived": true, - "created_at": "2019-08-24T14:15:22Z", - "created_by": { - "avatar_url": "http://example.com", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "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", - "error_code": "REQUIRED_TEMPLATE_VARIABLES", - "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "queue_position": 0, - "queue_size": 0, - "started_at": "2019-08-24T14:15:22Z", - "status": "pending", - "tags": { - "property1": "string", - "property2": "string" - }, - "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" - }, - "message": "string", - "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", - "warnings": ["UNSUPPORTED_WORKSPACES"] - } + { + "archived": true, + "created_at": "2019-08-24T14:15:22Z", + "created_by": { + "avatar_url": "http://example.com", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "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", + "error_code": "REQUIRED_TEMPLATE_VARIABLES", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "queue_position": 0, + "queue_size": 0, + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" + }, + "message": "string", + "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", + "warnings": ["UNSUPPORTED_WORKSPACES"] + } ] ``` @@ -1442,39 +1442,39 @@ curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion} \ ```json { - "archived": true, - "created_at": "2019-08-24T14:15:22Z", - "created_by": { - "avatar_url": "http://example.com", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "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", - "error_code": "REQUIRED_TEMPLATE_VARIABLES", - "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "queue_position": 0, - "queue_size": 0, - "started_at": "2019-08-24T14:15:22Z", - "status": "pending", - "tags": { - "property1": "string", - "property2": "string" - }, - "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" - }, - "message": "string", - "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", - "warnings": ["UNSUPPORTED_WORKSPACES"] + "archived": true, + "created_at": "2019-08-24T14:15:22Z", + "created_by": { + "avatar_url": "http://example.com", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "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", + "error_code": "REQUIRED_TEMPLATE_VARIABLES", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "queue_position": 0, + "queue_size": 0, + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" + }, + "message": "string", + "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", + "warnings": ["UNSUPPORTED_WORKSPACES"] } ``` @@ -1504,8 +1504,8 @@ curl -X PATCH http://coder-server:8080/api/v2/templateversions/{templateversion} ```json { - "message": "string", - "name": "string" + "message": "string", + "name": "string" } ``` @@ -1522,39 +1522,39 @@ curl -X PATCH http://coder-server:8080/api/v2/templateversions/{templateversion} ```json { - "archived": true, - "created_at": "2019-08-24T14:15:22Z", - "created_by": { - "avatar_url": "http://example.com", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "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", - "error_code": "REQUIRED_TEMPLATE_VARIABLES", - "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "queue_position": 0, - "queue_size": 0, - "started_at": "2019-08-24T14:15:22Z", - "status": "pending", - "tags": { - "property1": "string", - "property2": "string" - }, - "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" - }, - "message": "string", - "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", - "warnings": ["UNSUPPORTED_WORKSPACES"] + "archived": true, + "created_at": "2019-08-24T14:15:22Z", + "created_by": { + "avatar_url": "http://example.com", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "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", + "error_code": "REQUIRED_TEMPLATE_VARIABLES", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "queue_position": 0, + "queue_size": 0, + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" + }, + "message": "string", + "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", + "warnings": ["UNSUPPORTED_WORKSPACES"] } ``` @@ -1591,14 +1591,14 @@ curl -X POST http://coder-server:8080/api/v2/templateversions/{templateversion}/ ```json { - "detail": "string", - "message": "string", - "validations": [ - { - "detail": "string", - "field": "string" - } - ] + "detail": "string", + "message": "string", + "validations": [ + { + "detail": "string", + "field": "string" + } + ] } ``` @@ -1635,14 +1635,14 @@ curl -X PATCH http://coder-server:8080/api/v2/templateversions/{templateversion} ```json { - "detail": "string", - "message": "string", - "validations": [ - { - "detail": "string", - "field": "string" - } - ] + "detail": "string", + "message": "string", + "validations": [ + { + "detail": "string", + "field": "string" + } + ] } ``` @@ -1672,19 +1672,19 @@ curl -X POST http://coder-server:8080/api/v2/templateversions/{templateversion}/ ```json { - "rich_parameter_values": [ - { - "name": "string", - "value": "string" - } - ], - "user_variable_values": [ - { - "name": "string", - "value": "string" - } - ], - "workspace_name": "string" + "rich_parameter_values": [ + { + "name": "string", + "value": "string" + } + ], + "user_variable_values": [ + { + "name": "string", + "value": "string" + } + ], + "workspace_name": "string" } ``` @@ -1701,22 +1701,22 @@ curl -X POST http://coder-server:8080/api/v2/templateversions/{templateversion}/ ```json { - "canceled_at": "2019-08-24T14:15:22Z", - "completed_at": "2019-08-24T14:15:22Z", - "created_at": "2019-08-24T14:15:22Z", - "error": "string", - "error_code": "REQUIRED_TEMPLATE_VARIABLES", - "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "queue_position": 0, - "queue_size": 0, - "started_at": "2019-08-24T14:15:22Z", - "status": "pending", - "tags": { - "property1": "string", - "property2": "string" - }, - "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" + "canceled_at": "2019-08-24T14:15:22Z", + "completed_at": "2019-08-24T14:15:22Z", + "created_at": "2019-08-24T14:15:22Z", + "error": "string", + "error_code": "REQUIRED_TEMPLATE_VARIABLES", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "queue_position": 0, + "queue_size": 0, + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" } ``` @@ -1754,22 +1754,22 @@ curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/d ```json { - "canceled_at": "2019-08-24T14:15:22Z", - "completed_at": "2019-08-24T14:15:22Z", - "created_at": "2019-08-24T14:15:22Z", - "error": "string", - "error_code": "REQUIRED_TEMPLATE_VARIABLES", - "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "queue_position": 0, - "queue_size": 0, - "started_at": "2019-08-24T14:15:22Z", - "status": "pending", - "tags": { - "property1": "string", - "property2": "string" - }, - "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" + "canceled_at": "2019-08-24T14:15:22Z", + "completed_at": "2019-08-24T14:15:22Z", + "created_at": "2019-08-24T14:15:22Z", + "error": "string", + "error_code": "REQUIRED_TEMPLATE_VARIABLES", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "queue_position": 0, + "queue_size": 0, + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" } ``` @@ -1807,14 +1807,14 @@ curl -X PATCH http://coder-server:8080/api/v2/templateversions/{templateversion} ```json { - "detail": "string", - "message": "string", - "validations": [ - { - "detail": "string", - "field": "string" - } - ] + "detail": "string", + "message": "string", + "validations": [ + { + "detail": "string", + "field": "string" + } + ] } ``` @@ -1855,14 +1855,14 @@ curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/d ```json [ - { - "created_at": "2019-08-24T14:15:22Z", - "id": 0, - "log_level": "trace", - "log_source": "provisioner_daemon", - "output": "string", - "stage": "string" - } + { + "created_at": "2019-08-24T14:15:22Z", + "id": 0, + "log_level": "trace", + "log_source": "provisioner_daemon", + "output": "string", + "stage": "string" + } ] ``` @@ -1926,113 +1926,113 @@ curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/d ```json [ - { - "agents": [ - { - "api_version": "string", - "apps": [ - { - "command": "string", - "display_name": "string", - "external": true, - "health": "disabled", - "healthcheck": { - "interval": 0, - "threshold": 0, - "url": "string" - }, - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "sharing_level": "owner", - "slug": "string", - "subdomain": true, - "subdomain_name": "string", - "url": "string" - } - ], - "architecture": "string", - "connection_timeout_seconds": 0, - "created_at": "2019-08-24T14:15:22Z", - "directory": "string", - "disconnected_at": "2019-08-24T14:15:22Z", - "display_apps": ["vscode"], - "environment_variables": { - "property1": "string", - "property2": "string" - }, - "expanded_directory": "string", - "first_connected_at": "2019-08-24T14:15:22Z", - "health": { - "healthy": false, - "reason": "agent has lost connection" - }, - "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 - } - }, - "lifecycle_state": "created", - "log_sources": [ - { - "created_at": "2019-08-24T14:15:22Z", - "display_name": "string", - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" - } - ], - "logs_length": 0, - "logs_overflowed": true, - "name": "string", - "operating_system": "string", - "ready_at": "2019-08-24T14:15:22Z", - "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", - "scripts": [ - { - "cron": "string", - "log_path": "string", - "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", - "run_on_start": true, - "run_on_stop": true, - "script": "string", - "start_blocks_login": true, - "timeout": 0 - } - ], - "started_at": "2019-08-24T14:15:22Z", - "startup_script_behavior": "blocking", - "status": "connecting", - "subsystems": ["envbox"], - "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" - } + { + "agents": [ + { + "api_version": "string", + "apps": [ + { + "command": "string", + "display_name": "string", + "external": true, + "health": "disabled", + "healthcheck": { + "interval": 0, + "threshold": 0, + "url": "string" + }, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "sharing_level": "owner", + "slug": "string", + "subdomain": true, + "subdomain_name": "string", + "url": "string" + } + ], + "architecture": "string", + "connection_timeout_seconds": 0, + "created_at": "2019-08-24T14:15:22Z", + "directory": "string", + "disconnected_at": "2019-08-24T14:15:22Z", + "display_apps": ["vscode"], + "environment_variables": { + "property1": "string", + "property2": "string" + }, + "expanded_directory": "string", + "first_connected_at": "2019-08-24T14:15:22Z", + "health": { + "healthy": false, + "reason": "agent has lost connection" + }, + "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 + } + }, + "lifecycle_state": "created", + "log_sources": [ + { + "created_at": "2019-08-24T14:15:22Z", + "display_name": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" + } + ], + "logs_length": 0, + "logs_overflowed": true, + "name": "string", + "operating_system": "string", + "ready_at": "2019-08-24T14:15:22Z", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", + "scripts": [ + { + "cron": "string", + "log_path": "string", + "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", + "run_on_start": true, + "run_on_stop": true, + "script": "string", + "start_blocks_login": true, + "timeout": 0 + } + ], + "started_at": "2019-08-24T14:15:22Z", + "startup_script_behavior": "blocking", + "status": "connecting", + "subsystems": ["envbox"], + "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" + } ] ``` @@ -2187,15 +2187,15 @@ curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/e ```json [ - { - "authenticate_url": "string", - "authenticated": true, - "display_icon": "string", - "display_name": "string", - "id": "string", - "optional": true, - "type": "string" - } + { + "authenticate_url": "string", + "authenticated": true, + "display_icon": "string", + "display_name": "string", + "id": "string", + "optional": true, + "type": "string" + } ] ``` @@ -2250,14 +2250,14 @@ curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/l ```json [ - { - "created_at": "2019-08-24T14:15:22Z", - "id": 0, - "log_level": "trace", - "log_source": "provisioner_daemon", - "output": "string", - "stage": "string" - } + { + "created_at": "2019-08-24T14:15:22Z", + "id": 0, + "log_level": "trace", + "log_source": "provisioner_daemon", + "output": "string", + "stage": "string" + } ] ``` @@ -2346,113 +2346,113 @@ curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/r ```json [ - { - "agents": [ - { - "api_version": "string", - "apps": [ - { - "command": "string", - "display_name": "string", - "external": true, - "health": "disabled", - "healthcheck": { - "interval": 0, - "threshold": 0, - "url": "string" - }, - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "sharing_level": "owner", - "slug": "string", - "subdomain": true, - "subdomain_name": "string", - "url": "string" - } - ], - "architecture": "string", - "connection_timeout_seconds": 0, - "created_at": "2019-08-24T14:15:22Z", - "directory": "string", - "disconnected_at": "2019-08-24T14:15:22Z", - "display_apps": ["vscode"], - "environment_variables": { - "property1": "string", - "property2": "string" - }, - "expanded_directory": "string", - "first_connected_at": "2019-08-24T14:15:22Z", - "health": { - "healthy": false, - "reason": "agent has lost connection" - }, - "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 - } - }, - "lifecycle_state": "created", - "log_sources": [ - { - "created_at": "2019-08-24T14:15:22Z", - "display_name": "string", - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" - } - ], - "logs_length": 0, - "logs_overflowed": true, - "name": "string", - "operating_system": "string", - "ready_at": "2019-08-24T14:15:22Z", - "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", - "scripts": [ - { - "cron": "string", - "log_path": "string", - "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", - "run_on_start": true, - "run_on_stop": true, - "script": "string", - "start_blocks_login": true, - "timeout": 0 - } - ], - "started_at": "2019-08-24T14:15:22Z", - "startup_script_behavior": "blocking", - "status": "connecting", - "subsystems": ["envbox"], - "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" - } + { + "agents": [ + { + "api_version": "string", + "apps": [ + { + "command": "string", + "display_name": "string", + "external": true, + "health": "disabled", + "healthcheck": { + "interval": 0, + "threshold": 0, + "url": "string" + }, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "sharing_level": "owner", + "slug": "string", + "subdomain": true, + "subdomain_name": "string", + "url": "string" + } + ], + "architecture": "string", + "connection_timeout_seconds": 0, + "created_at": "2019-08-24T14:15:22Z", + "directory": "string", + "disconnected_at": "2019-08-24T14:15:22Z", + "display_apps": ["vscode"], + "environment_variables": { + "property1": "string", + "property2": "string" + }, + "expanded_directory": "string", + "first_connected_at": "2019-08-24T14:15:22Z", + "health": { + "healthy": false, + "reason": "agent has lost connection" + }, + "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 + } + }, + "lifecycle_state": "created", + "log_sources": [ + { + "created_at": "2019-08-24T14:15:22Z", + "display_name": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" + } + ], + "logs_length": 0, + "logs_overflowed": true, + "name": "string", + "operating_system": "string", + "ready_at": "2019-08-24T14:15:22Z", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", + "scripts": [ + { + "cron": "string", + "log_path": "string", + "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", + "run_on_start": true, + "run_on_stop": true, + "script": "string", + "start_blocks_login": true, + "timeout": 0 + } + ], + "started_at": "2019-08-24T14:15:22Z", + "startup_script_behavior": "blocking", + "status": "connecting", + "subsystems": ["envbox"], + "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" + } ] ``` @@ -2607,31 +2607,31 @@ curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/r ```json [ - { - "default_value": "string", - "description": "string", - "description_plaintext": "string", - "display_name": "string", - "ephemeral": true, - "icon": "string", - "mutable": true, - "name": "string", - "options": [ - { - "description": "string", - "icon": "string", - "name": "string", - "value": "string" - } - ], - "required": true, - "type": "string", - "validation_error": "string", - "validation_max": 0, - "validation_min": 0, - "validation_monotonic": "increasing", - "validation_regex": "string" - } + { + "default_value": "string", + "description": "string", + "description_plaintext": "string", + "display_name": "string", + "ephemeral": true, + "icon": "string", + "mutable": true, + "name": "string", + "options": [ + { + "description": "string", + "icon": "string", + "name": "string", + "value": "string" + } + ], + "required": true, + "type": "string", + "validation_error": "string", + "validation_max": 0, + "validation_min": 0, + "validation_monotonic": "increasing", + "validation_regex": "string" + } ] ``` @@ -2733,14 +2733,14 @@ curl -X POST http://coder-server:8080/api/v2/templateversions/{templateversion}/ ```json { - "detail": "string", - "message": "string", - "validations": [ - { - "detail": "string", - "field": "string" - } - ] + "detail": "string", + "message": "string", + "validations": [ + { + "detail": "string", + "field": "string" + } + ] } ``` @@ -2777,15 +2777,15 @@ curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/v ```json [ - { - "default_value": "string", - "description": "string", - "name": "string", - "required": true, - "sensitive": true, - "type": "string", - "value": "string" - } + { + "default_value": "string", + "description": "string", + "name": "string", + "required": true, + "sensitive": true, + "type": "string", + "value": "string" + } ] ``` diff --git a/docs/reference/api/users.md b/docs/reference/api/users.md index 05af30df86..2cca07030c 100644 --- a/docs/reference/api/users.md +++ b/docs/reference/api/users.md @@ -28,30 +28,30 @@ curl -X GET http://coder-server:8080/api/v2/users \ ```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", - "login_type": "", - "name": "string", - "organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "roles": [ - { - "display_name": "string", - "name": "string", - "organization_id": "string" - } - ], - "status": "active", - "theme_preference": "string", - "updated_at": "2019-08-24T14:15:22Z", - "username": "string" - } - ] + "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", + "login_type": "", + "name": "string", + "organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "roles": [ + { + "display_name": "string", + "name": "string", + "organization_id": "string" + } + ], + "status": "active", + "theme_preference": "string", + "updated_at": "2019-08-24T14:15:22Z", + "username": "string" + } + ] } ``` @@ -81,13 +81,13 @@ curl -X POST http://coder-server:8080/api/v2/users \ ```json { - "disable_login": true, - "email": "user@example.com", - "login_type": "", - "name": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "password": "string", - "username": "string" + "disable_login": true, + "email": "user@example.com", + "login_type": "", + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "password": "string", + "username": "string" } ``` @@ -103,25 +103,25 @@ curl -X POST http://coder-server:8080/api/v2/users \ ```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", - "login_type": "", - "name": "string", - "organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "roles": [ - { - "display_name": "string", - "name": "string", - "organization_id": "string" - } - ], - "status": "active", - "theme_preference": "string", - "updated_at": "2019-08-24T14:15:22Z", - "username": "string" + "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", + "login_type": "", + "name": "string", + "organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "roles": [ + { + "display_name": "string", + "name": "string", + "organization_id": "string" + } + ], + "status": "active", + "theme_preference": "string", + "updated_at": "2019-08-24T14:15:22Z", + "username": "string" } ``` @@ -152,18 +152,18 @@ curl -X GET http://coder-server:8080/api/v2/users/authmethods \ ```json { - "github": { - "enabled": true - }, - "oidc": { - "enabled": true, - "iconUrl": "string", - "signInText": "string" - }, - "password": { - "enabled": true - }, - "terms_of_service_url": "string" + "github": { + "enabled": true + }, + "oidc": { + "enabled": true, + "iconUrl": "string", + "signInText": "string" + }, + "password": { + "enabled": true + }, + "terms_of_service_url": "string" } ``` @@ -194,14 +194,14 @@ curl -X GET http://coder-server:8080/api/v2/users/first \ ```json { - "detail": "string", - "message": "string", - "validations": [ - { - "detail": "string", - "field": "string" - } - ] + "detail": "string", + "message": "string", + "validations": [ + { + "detail": "string", + "field": "string" + } + ] } ``` @@ -231,20 +231,20 @@ curl -X POST http://coder-server:8080/api/v2/users/first \ ```json { - "email": "string", - "name": "string", - "password": "string", - "trial": true, - "trial_info": { - "company_name": "string", - "country": "string", - "developers": "string", - "first_name": "string", - "job_title": "string", - "last_name": "string", - "phone_number": "string" - }, - "username": "string" + "email": "string", + "name": "string", + "password": "string", + "trial": true, + "trial_info": { + "company_name": "string", + "country": "string", + "developers": "string", + "first_name": "string", + "job_title": "string", + "last_name": "string", + "phone_number": "string" + }, + "username": "string" } ``` @@ -260,8 +260,8 @@ curl -X POST http://coder-server:8080/api/v2/users/first \ ```json { - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5" + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5" } ``` @@ -292,14 +292,14 @@ curl -X POST http://coder-server:8080/api/v2/users/logout \ ```json { - "detail": "string", - "message": "string", - "validations": [ - { - "detail": "string", - "field": "string" - } - ] + "detail": "string", + "message": "string", + "validations": [ + { + "detail": "string", + "field": "string" + } + ] } ``` @@ -376,25 +376,25 @@ curl -X GET http://coder-server:8080/api/v2/users/{user} \ ```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", - "login_type": "", - "name": "string", - "organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "roles": [ - { - "display_name": "string", - "name": "string", - "organization_id": "string" - } - ], - "status": "active", - "theme_preference": "string", - "updated_at": "2019-08-24T14:15:22Z", - "username": "string" + "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", + "login_type": "", + "name": "string", + "organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "roles": [ + { + "display_name": "string", + "name": "string", + "organization_id": "string" + } + ], + "status": "active", + "theme_preference": "string", + "updated_at": "2019-08-24T14:15:22Z", + "username": "string" } ``` @@ -450,7 +450,7 @@ curl -X PUT http://coder-server:8080/api/v2/users/{user}/appearance \ ```json { - "theme_preference": "string" + "theme_preference": "string" } ``` @@ -467,25 +467,25 @@ curl -X PUT http://coder-server:8080/api/v2/users/{user}/appearance \ ```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", - "login_type": "", - "name": "string", - "organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "roles": [ - { - "display_name": "string", - "name": "string", - "organization_id": "string" - } - ], - "status": "active", - "theme_preference": "string", - "updated_at": "2019-08-24T14:15:22Z", - "username": "string" + "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", + "login_type": "", + "name": "string", + "organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "roles": [ + { + "display_name": "string", + "name": "string", + "organization_id": "string" + } + ], + "status": "active", + "theme_preference": "string", + "updated_at": "2019-08-24T14:15:22Z", + "username": "string" } ``` @@ -523,10 +523,10 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/autofill-parameters?tem ```json [ - { - "name": "string", - "value": "string" - } + { + "name": "string", + "value": "string" + } ] ``` @@ -573,10 +573,10 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/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" + "created_at": "2019-08-24T14:15:22Z", + "public_key": "string", + "updated_at": "2019-08-24T14:15:22Z", + "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5" } ``` @@ -613,10 +613,10 @@ curl -X PUT http://coder-server:8080/api/v2/users/{user}/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" + "created_at": "2019-08-24T14:15:22Z", + "public_key": "string", + "updated_at": "2019-08-24T14:15:22Z", + "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5" } ``` @@ -653,7 +653,7 @@ curl -X POST http://coder-server:8080/api/v2/users/{user}/keys \ ```json { - "key": "string" + "key": "string" } ``` @@ -690,18 +690,18 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/keys/tokens \ ```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", - "token_name": "string", - "updated_at": "2019-08-24T14:15:22Z", - "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5" - } + { + "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", + "token_name": "string", + "updated_at": "2019-08-24T14:15:22Z", + "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5" + } ] ``` @@ -760,9 +760,9 @@ curl -X POST http://coder-server:8080/api/v2/users/{user}/keys/tokens \ ```json { - "lifetime": 0, - "scope": "all", - "token_name": "string" + "lifetime": 0, + "scope": "all", + "token_name": "string" } ``` @@ -779,7 +779,7 @@ curl -X POST http://coder-server:8080/api/v2/users/{user}/keys/tokens \ ```json { - "key": "string" + "key": "string" } ``` @@ -817,16 +817,16 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/keys/tokens/{keyname} \ ```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", - "token_name": "string", - "updated_at": "2019-08-24T14:15:22Z", - "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5" + "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", + "token_name": "string", + "updated_at": "2019-08-24T14:15:22Z", + "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5" } ``` @@ -864,16 +864,16 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/keys/{keyid} \ ```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", - "token_name": "string", - "updated_at": "2019-08-24T14:15:22Z", - "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5" + "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", + "token_name": "string", + "updated_at": "2019-08-24T14:15:22Z", + "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5" } ``` @@ -937,7 +937,7 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/login-type \ ```json { - "login_type": "" + "login_type": "" } ``` @@ -974,16 +974,16 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/organizations \ ```json [ - { - "created_at": "2019-08-24T14:15:22Z", - "description": "string", - "display_name": "string", - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "is_default": true, - "name": "string", - "updated_at": "2019-08-24T14:15:22Z" - } + { + "created_at": "2019-08-24T14:15:22Z", + "description": "string", + "display_name": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "is_default": true, + "name": "string", + "updated_at": "2019-08-24T14:15:22Z" + } ] ``` @@ -1037,14 +1037,14 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/organizations/{organiza ```json { - "created_at": "2019-08-24T14:15:22Z", - "description": "string", - "display_name": "string", - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "is_default": true, - "name": "string", - "updated_at": "2019-08-24T14:15:22Z" + "created_at": "2019-08-24T14:15:22Z", + "description": "string", + "display_name": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "is_default": true, + "name": "string", + "updated_at": "2019-08-24T14:15:22Z" } ``` @@ -1073,8 +1073,8 @@ curl -X PUT http://coder-server:8080/api/v2/users/{user}/password \ ```json { - "old_password": "string", - "password": "string" + "old_password": "string", + "password": "string" } ``` @@ -1111,8 +1111,8 @@ curl -X PUT http://coder-server:8080/api/v2/users/{user}/profile \ ```json { - "name": "string", - "username": "string" + "name": "string", + "username": "string" } ``` @@ -1129,25 +1129,25 @@ curl -X PUT http://coder-server:8080/api/v2/users/{user}/profile \ ```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", - "login_type": "", - "name": "string", - "organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "roles": [ - { - "display_name": "string", - "name": "string", - "organization_id": "string" - } - ], - "status": "active", - "theme_preference": "string", - "updated_at": "2019-08-24T14:15:22Z", - "username": "string" + "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", + "login_type": "", + "name": "string", + "organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "roles": [ + { + "display_name": "string", + "name": "string", + "organization_id": "string" + } + ], + "status": "active", + "theme_preference": "string", + "updated_at": "2019-08-24T14:15:22Z", + "username": "string" } ``` @@ -1184,25 +1184,25 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/roles \ ```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", - "login_type": "", - "name": "string", - "organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "roles": [ - { - "display_name": "string", - "name": "string", - "organization_id": "string" - } - ], - "status": "active", - "theme_preference": "string", - "updated_at": "2019-08-24T14:15:22Z", - "username": "string" + "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", + "login_type": "", + "name": "string", + "organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "roles": [ + { + "display_name": "string", + "name": "string", + "organization_id": "string" + } + ], + "status": "active", + "theme_preference": "string", + "updated_at": "2019-08-24T14:15:22Z", + "username": "string" } ``` @@ -1232,7 +1232,7 @@ curl -X PUT http://coder-server:8080/api/v2/users/{user}/roles \ ```json { - "roles": ["string"] + "roles": ["string"] } ``` @@ -1249,25 +1249,25 @@ curl -X PUT http://coder-server:8080/api/v2/users/{user}/roles \ ```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", - "login_type": "", - "name": "string", - "organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "roles": [ - { - "display_name": "string", - "name": "string", - "organization_id": "string" - } - ], - "status": "active", - "theme_preference": "string", - "updated_at": "2019-08-24T14:15:22Z", - "username": "string" + "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", + "login_type": "", + "name": "string", + "organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "roles": [ + { + "display_name": "string", + "name": "string", + "organization_id": "string" + } + ], + "status": "active", + "theme_preference": "string", + "updated_at": "2019-08-24T14:15:22Z", + "username": "string" } ``` @@ -1304,25 +1304,25 @@ curl -X PUT http://coder-server:8080/api/v2/users/{user}/status/activate \ ```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", - "login_type": "", - "name": "string", - "organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "roles": [ - { - "display_name": "string", - "name": "string", - "organization_id": "string" - } - ], - "status": "active", - "theme_preference": "string", - "updated_at": "2019-08-24T14:15:22Z", - "username": "string" + "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", + "login_type": "", + "name": "string", + "organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "roles": [ + { + "display_name": "string", + "name": "string", + "organization_id": "string" + } + ], + "status": "active", + "theme_preference": "string", + "updated_at": "2019-08-24T14:15:22Z", + "username": "string" } ``` @@ -1359,25 +1359,25 @@ curl -X PUT http://coder-server:8080/api/v2/users/{user}/status/suspend \ ```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", - "login_type": "", - "name": "string", - "organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "roles": [ - { - "display_name": "string", - "name": "string", - "organization_id": "string" - } - ], - "status": "active", - "theme_preference": "string", - "updated_at": "2019-08-24T14:15:22Z", - "username": "string" + "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", + "login_type": "", + "name": "string", + "organization_ids": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "roles": [ + { + "display_name": "string", + "name": "string", + "organization_id": "string" + } + ], + "status": "active", + "theme_preference": "string", + "updated_at": "2019-08-24T14:15:22Z", + "username": "string" } ``` diff --git a/docs/reference/api/workspaceproxies.md b/docs/reference/api/workspaceproxies.md index 2113d53d16..35e9e6d84e 100644 --- a/docs/reference/api/workspaceproxies.md +++ b/docs/reference/api/workspaceproxies.md @@ -19,17 +19,17 @@ curl -X GET http://coder-server:8080/api/v2/regions \ ```json { - "regions": [ - { - "display_name": "string", - "healthy": true, - "icon_url": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "name": "string", - "path_app_url": "string", - "wildcard_hostname": "string" - } - ] + "regions": [ + { + "display_name": "string", + "healthy": true, + "icon_url": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "string", + "path_app_url": "string", + "wildcard_hostname": "string" + } + ] } ``` diff --git a/docs/reference/api/workspaces.md b/docs/reference/api/workspaces.md index 10d4680430..11b2a6283e 100644 --- a/docs/reference/api/workspaces.md +++ b/docs/reference/api/workspaces.md @@ -23,18 +23,18 @@ of the template will be used. ```json { - "automatic_updates": "always", - "autostart_schedule": "string", - "name": "string", - "rich_parameter_values": [ - { - "name": "string", - "value": "string" - } - ], - "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", - "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1", - "ttl_ms": 0 + "automatic_updates": "always", + "autostart_schedule": "string", + "name": "string", + "rich_parameter_values": [ + { + "name": "string", + "value": "string" + } + ], + "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", + "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1", + "ttl_ms": 0 } ``` @@ -52,183 +52,183 @@ of the template will be used. ```json { - "allow_renames": true, - "automatic_updates": "always", - "autostart_schedule": "string", - "created_at": "2019-08-24T14:15:22Z", - "deleting_at": "2019-08-24T14:15:22Z", - "dormant_at": "2019-08-24T14:15:22Z", - "favorite": true, - "health": { - "failing_agents": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "healthy": false - }, - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "last_used_at": "2019-08-24T14:15:22Z", - "latest_build": { - "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", - "error_code": "REQUIRED_TEMPLATE_VARIABLES", - "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "queue_position": 0, - "queue_size": 0, - "started_at": "2019-08-24T14:15:22Z", - "status": "pending", - "tags": { - "property1": "string", - "property2": "string" - }, - "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" - }, - "max_deadline": "2019-08-24T14:15:22Z", - "reason": "initiator", - "resources": [ - { - "agents": [ - { - "api_version": "string", - "apps": [ - { - "command": "string", - "display_name": "string", - "external": true, - "health": "disabled", - "healthcheck": { - "interval": 0, - "threshold": 0, - "url": "string" - }, - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "sharing_level": "owner", - "slug": "string", - "subdomain": true, - "subdomain_name": "string", - "url": "string" - } - ], - "architecture": "string", - "connection_timeout_seconds": 0, - "created_at": "2019-08-24T14:15:22Z", - "directory": "string", - "disconnected_at": "2019-08-24T14:15:22Z", - "display_apps": ["vscode"], - "environment_variables": { - "property1": "string", - "property2": "string" - }, - "expanded_directory": "string", - "first_connected_at": "2019-08-24T14:15:22Z", - "health": { - "healthy": false, - "reason": "agent has lost connection" - }, - "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 - } - }, - "lifecycle_state": "created", - "log_sources": [ - { - "created_at": "2019-08-24T14:15:22Z", - "display_name": "string", - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" - } - ], - "logs_length": 0, - "logs_overflowed": true, - "name": "string", - "operating_system": "string", - "ready_at": "2019-08-24T14:15:22Z", - "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", - "scripts": [ - { - "cron": "string", - "log_path": "string", - "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", - "run_on_start": true, - "run_on_stop": true, - "script": "string", - "start_blocks_login": true, - "timeout": 0 - } - ], - "started_at": "2019-08-24T14:15:22Z", - "startup_script_behavior": "blocking", - "status": "connecting", - "subsystems": ["envbox"], - "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_avatar_url": "string", - "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7", - "workspace_owner_name": "string" - }, - "name": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "organization_name": "string", - "outdated": true, - "owner_avatar_url": "string", - "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05", - "owner_name": "string", - "template_active_version_id": "b0da9c29-67d8-4c87-888c-bafe356f7f3c", - "template_allow_user_cancel_workspace_jobs": true, - "template_display_name": "string", - "template_icon": "string", - "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", - "template_name": "string", - "template_require_active_version": true, - "ttl_ms": 0, - "updated_at": "2019-08-24T14:15:22Z" + "allow_renames": true, + "automatic_updates": "always", + "autostart_schedule": "string", + "created_at": "2019-08-24T14:15:22Z", + "deleting_at": "2019-08-24T14:15:22Z", + "dormant_at": "2019-08-24T14:15:22Z", + "favorite": true, + "health": { + "failing_agents": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "healthy": false + }, + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "last_used_at": "2019-08-24T14:15:22Z", + "latest_build": { + "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", + "error_code": "REQUIRED_TEMPLATE_VARIABLES", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "queue_position": 0, + "queue_size": 0, + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" + }, + "max_deadline": "2019-08-24T14:15:22Z", + "reason": "initiator", + "resources": [ + { + "agents": [ + { + "api_version": "string", + "apps": [ + { + "command": "string", + "display_name": "string", + "external": true, + "health": "disabled", + "healthcheck": { + "interval": 0, + "threshold": 0, + "url": "string" + }, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "sharing_level": "owner", + "slug": "string", + "subdomain": true, + "subdomain_name": "string", + "url": "string" + } + ], + "architecture": "string", + "connection_timeout_seconds": 0, + "created_at": "2019-08-24T14:15:22Z", + "directory": "string", + "disconnected_at": "2019-08-24T14:15:22Z", + "display_apps": ["vscode"], + "environment_variables": { + "property1": "string", + "property2": "string" + }, + "expanded_directory": "string", + "first_connected_at": "2019-08-24T14:15:22Z", + "health": { + "healthy": false, + "reason": "agent has lost connection" + }, + "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 + } + }, + "lifecycle_state": "created", + "log_sources": [ + { + "created_at": "2019-08-24T14:15:22Z", + "display_name": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" + } + ], + "logs_length": 0, + "logs_overflowed": true, + "name": "string", + "operating_system": "string", + "ready_at": "2019-08-24T14:15:22Z", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", + "scripts": [ + { + "cron": "string", + "log_path": "string", + "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", + "run_on_start": true, + "run_on_stop": true, + "script": "string", + "start_blocks_login": true, + "timeout": 0 + } + ], + "started_at": "2019-08-24T14:15:22Z", + "startup_script_behavior": "blocking", + "status": "connecting", + "subsystems": ["envbox"], + "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_avatar_url": "string", + "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7", + "workspace_owner_name": "string" + }, + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "organization_name": "string", + "outdated": true, + "owner_avatar_url": "string", + "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05", + "owner_name": "string", + "template_active_version_id": "b0da9c29-67d8-4c87-888c-bafe356f7f3c", + "template_allow_user_cancel_workspace_jobs": true, + "template_display_name": "string", + "template_icon": "string", + "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", + "template_name": "string", + "template_require_active_version": true, + "ttl_ms": 0, + "updated_at": "2019-08-24T14:15:22Z" } ``` @@ -267,183 +267,183 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/workspace/{workspacenam ```json { - "allow_renames": true, - "automatic_updates": "always", - "autostart_schedule": "string", - "created_at": "2019-08-24T14:15:22Z", - "deleting_at": "2019-08-24T14:15:22Z", - "dormant_at": "2019-08-24T14:15:22Z", - "favorite": true, - "health": { - "failing_agents": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "healthy": false - }, - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "last_used_at": "2019-08-24T14:15:22Z", - "latest_build": { - "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", - "error_code": "REQUIRED_TEMPLATE_VARIABLES", - "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "queue_position": 0, - "queue_size": 0, - "started_at": "2019-08-24T14:15:22Z", - "status": "pending", - "tags": { - "property1": "string", - "property2": "string" - }, - "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" - }, - "max_deadline": "2019-08-24T14:15:22Z", - "reason": "initiator", - "resources": [ - { - "agents": [ - { - "api_version": "string", - "apps": [ - { - "command": "string", - "display_name": "string", - "external": true, - "health": "disabled", - "healthcheck": { - "interval": 0, - "threshold": 0, - "url": "string" - }, - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "sharing_level": "owner", - "slug": "string", - "subdomain": true, - "subdomain_name": "string", - "url": "string" - } - ], - "architecture": "string", - "connection_timeout_seconds": 0, - "created_at": "2019-08-24T14:15:22Z", - "directory": "string", - "disconnected_at": "2019-08-24T14:15:22Z", - "display_apps": ["vscode"], - "environment_variables": { - "property1": "string", - "property2": "string" - }, - "expanded_directory": "string", - "first_connected_at": "2019-08-24T14:15:22Z", - "health": { - "healthy": false, - "reason": "agent has lost connection" - }, - "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 - } - }, - "lifecycle_state": "created", - "log_sources": [ - { - "created_at": "2019-08-24T14:15:22Z", - "display_name": "string", - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" - } - ], - "logs_length": 0, - "logs_overflowed": true, - "name": "string", - "operating_system": "string", - "ready_at": "2019-08-24T14:15:22Z", - "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", - "scripts": [ - { - "cron": "string", - "log_path": "string", - "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", - "run_on_start": true, - "run_on_stop": true, - "script": "string", - "start_blocks_login": true, - "timeout": 0 - } - ], - "started_at": "2019-08-24T14:15:22Z", - "startup_script_behavior": "blocking", - "status": "connecting", - "subsystems": ["envbox"], - "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_avatar_url": "string", - "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7", - "workspace_owner_name": "string" - }, - "name": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "organization_name": "string", - "outdated": true, - "owner_avatar_url": "string", - "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05", - "owner_name": "string", - "template_active_version_id": "b0da9c29-67d8-4c87-888c-bafe356f7f3c", - "template_allow_user_cancel_workspace_jobs": true, - "template_display_name": "string", - "template_icon": "string", - "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", - "template_name": "string", - "template_require_active_version": true, - "ttl_ms": 0, - "updated_at": "2019-08-24T14:15:22Z" + "allow_renames": true, + "automatic_updates": "always", + "autostart_schedule": "string", + "created_at": "2019-08-24T14:15:22Z", + "deleting_at": "2019-08-24T14:15:22Z", + "dormant_at": "2019-08-24T14:15:22Z", + "favorite": true, + "health": { + "failing_agents": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "healthy": false + }, + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "last_used_at": "2019-08-24T14:15:22Z", + "latest_build": { + "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", + "error_code": "REQUIRED_TEMPLATE_VARIABLES", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "queue_position": 0, + "queue_size": 0, + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" + }, + "max_deadline": "2019-08-24T14:15:22Z", + "reason": "initiator", + "resources": [ + { + "agents": [ + { + "api_version": "string", + "apps": [ + { + "command": "string", + "display_name": "string", + "external": true, + "health": "disabled", + "healthcheck": { + "interval": 0, + "threshold": 0, + "url": "string" + }, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "sharing_level": "owner", + "slug": "string", + "subdomain": true, + "subdomain_name": "string", + "url": "string" + } + ], + "architecture": "string", + "connection_timeout_seconds": 0, + "created_at": "2019-08-24T14:15:22Z", + "directory": "string", + "disconnected_at": "2019-08-24T14:15:22Z", + "display_apps": ["vscode"], + "environment_variables": { + "property1": "string", + "property2": "string" + }, + "expanded_directory": "string", + "first_connected_at": "2019-08-24T14:15:22Z", + "health": { + "healthy": false, + "reason": "agent has lost connection" + }, + "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 + } + }, + "lifecycle_state": "created", + "log_sources": [ + { + "created_at": "2019-08-24T14:15:22Z", + "display_name": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" + } + ], + "logs_length": 0, + "logs_overflowed": true, + "name": "string", + "operating_system": "string", + "ready_at": "2019-08-24T14:15:22Z", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", + "scripts": [ + { + "cron": "string", + "log_path": "string", + "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", + "run_on_start": true, + "run_on_stop": true, + "script": "string", + "start_blocks_login": true, + "timeout": 0 + } + ], + "started_at": "2019-08-24T14:15:22Z", + "startup_script_behavior": "blocking", + "status": "connecting", + "subsystems": ["envbox"], + "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_avatar_url": "string", + "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7", + "workspace_owner_name": "string" + }, + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "organization_name": "string", + "outdated": true, + "owner_avatar_url": "string", + "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05", + "owner_name": "string", + "template_active_version_id": "b0da9c29-67d8-4c87-888c-bafe356f7f3c", + "template_allow_user_cancel_workspace_jobs": true, + "template_display_name": "string", + "template_icon": "string", + "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", + "template_name": "string", + "template_require_active_version": true, + "ttl_ms": 0, + "updated_at": "2019-08-24T14:15:22Z" } ``` @@ -478,18 +478,18 @@ of the template will be used. ```json { - "automatic_updates": "always", - "autostart_schedule": "string", - "name": "string", - "rich_parameter_values": [ - { - "name": "string", - "value": "string" - } - ], - "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", - "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1", - "ttl_ms": 0 + "automatic_updates": "always", + "autostart_schedule": "string", + "name": "string", + "rich_parameter_values": [ + { + "name": "string", + "value": "string" + } + ], + "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", + "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1", + "ttl_ms": 0 } ``` @@ -506,183 +506,183 @@ of the template will be used. ```json { - "allow_renames": true, - "automatic_updates": "always", - "autostart_schedule": "string", - "created_at": "2019-08-24T14:15:22Z", - "deleting_at": "2019-08-24T14:15:22Z", - "dormant_at": "2019-08-24T14:15:22Z", - "favorite": true, - "health": { - "failing_agents": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "healthy": false - }, - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "last_used_at": "2019-08-24T14:15:22Z", - "latest_build": { - "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", - "error_code": "REQUIRED_TEMPLATE_VARIABLES", - "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "queue_position": 0, - "queue_size": 0, - "started_at": "2019-08-24T14:15:22Z", - "status": "pending", - "tags": { - "property1": "string", - "property2": "string" - }, - "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" - }, - "max_deadline": "2019-08-24T14:15:22Z", - "reason": "initiator", - "resources": [ - { - "agents": [ - { - "api_version": "string", - "apps": [ - { - "command": "string", - "display_name": "string", - "external": true, - "health": "disabled", - "healthcheck": { - "interval": 0, - "threshold": 0, - "url": "string" - }, - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "sharing_level": "owner", - "slug": "string", - "subdomain": true, - "subdomain_name": "string", - "url": "string" - } - ], - "architecture": "string", - "connection_timeout_seconds": 0, - "created_at": "2019-08-24T14:15:22Z", - "directory": "string", - "disconnected_at": "2019-08-24T14:15:22Z", - "display_apps": ["vscode"], - "environment_variables": { - "property1": "string", - "property2": "string" - }, - "expanded_directory": "string", - "first_connected_at": "2019-08-24T14:15:22Z", - "health": { - "healthy": false, - "reason": "agent has lost connection" - }, - "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 - } - }, - "lifecycle_state": "created", - "log_sources": [ - { - "created_at": "2019-08-24T14:15:22Z", - "display_name": "string", - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" - } - ], - "logs_length": 0, - "logs_overflowed": true, - "name": "string", - "operating_system": "string", - "ready_at": "2019-08-24T14:15:22Z", - "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", - "scripts": [ - { - "cron": "string", - "log_path": "string", - "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", - "run_on_start": true, - "run_on_stop": true, - "script": "string", - "start_blocks_login": true, - "timeout": 0 - } - ], - "started_at": "2019-08-24T14:15:22Z", - "startup_script_behavior": "blocking", - "status": "connecting", - "subsystems": ["envbox"], - "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_avatar_url": "string", - "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7", - "workspace_owner_name": "string" - }, - "name": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "organization_name": "string", - "outdated": true, - "owner_avatar_url": "string", - "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05", - "owner_name": "string", - "template_active_version_id": "b0da9c29-67d8-4c87-888c-bafe356f7f3c", - "template_allow_user_cancel_workspace_jobs": true, - "template_display_name": "string", - "template_icon": "string", - "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", - "template_name": "string", - "template_require_active_version": true, - "ttl_ms": 0, - "updated_at": "2019-08-24T14:15:22Z" + "allow_renames": true, + "automatic_updates": "always", + "autostart_schedule": "string", + "created_at": "2019-08-24T14:15:22Z", + "deleting_at": "2019-08-24T14:15:22Z", + "dormant_at": "2019-08-24T14:15:22Z", + "favorite": true, + "health": { + "failing_agents": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "healthy": false + }, + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "last_used_at": "2019-08-24T14:15:22Z", + "latest_build": { + "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", + "error_code": "REQUIRED_TEMPLATE_VARIABLES", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "queue_position": 0, + "queue_size": 0, + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" + }, + "max_deadline": "2019-08-24T14:15:22Z", + "reason": "initiator", + "resources": [ + { + "agents": [ + { + "api_version": "string", + "apps": [ + { + "command": "string", + "display_name": "string", + "external": true, + "health": "disabled", + "healthcheck": { + "interval": 0, + "threshold": 0, + "url": "string" + }, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "sharing_level": "owner", + "slug": "string", + "subdomain": true, + "subdomain_name": "string", + "url": "string" + } + ], + "architecture": "string", + "connection_timeout_seconds": 0, + "created_at": "2019-08-24T14:15:22Z", + "directory": "string", + "disconnected_at": "2019-08-24T14:15:22Z", + "display_apps": ["vscode"], + "environment_variables": { + "property1": "string", + "property2": "string" + }, + "expanded_directory": "string", + "first_connected_at": "2019-08-24T14:15:22Z", + "health": { + "healthy": false, + "reason": "agent has lost connection" + }, + "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 + } + }, + "lifecycle_state": "created", + "log_sources": [ + { + "created_at": "2019-08-24T14:15:22Z", + "display_name": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" + } + ], + "logs_length": 0, + "logs_overflowed": true, + "name": "string", + "operating_system": "string", + "ready_at": "2019-08-24T14:15:22Z", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", + "scripts": [ + { + "cron": "string", + "log_path": "string", + "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", + "run_on_start": true, + "run_on_stop": true, + "script": "string", + "start_blocks_login": true, + "timeout": 0 + } + ], + "started_at": "2019-08-24T14:15:22Z", + "startup_script_behavior": "blocking", + "status": "connecting", + "subsystems": ["envbox"], + "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_avatar_url": "string", + "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7", + "workspace_owner_name": "string" + }, + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "organization_name": "string", + "outdated": true, + "owner_avatar_url": "string", + "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05", + "owner_name": "string", + "template_active_version_id": "b0da9c29-67d8-4c87-888c-bafe356f7f3c", + "template_allow_user_cancel_workspace_jobs": true, + "template_display_name": "string", + "template_icon": "string", + "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", + "template_name": "string", + "template_require_active_version": true, + "ttl_ms": 0, + "updated_at": "2019-08-24T14:15:22Z" } ``` @@ -721,184 +721,184 @@ curl -X GET http://coder-server:8080/api/v2/workspaces \ ```json { - "count": 0, - "workspaces": [ - { - "allow_renames": true, - "automatic_updates": "always", - "autostart_schedule": "string", - "created_at": "2019-08-24T14:15:22Z", - "deleting_at": "2019-08-24T14:15:22Z", - "dormant_at": "2019-08-24T14:15:22Z", - "favorite": true, - "health": { - "failing_agents": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "healthy": false - }, - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "last_used_at": "2019-08-24T14:15:22Z", - "latest_build": { - "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", - "error_code": "REQUIRED_TEMPLATE_VARIABLES", - "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "queue_position": 0, - "queue_size": 0, - "started_at": "2019-08-24T14:15:22Z", - "status": "pending", - "tags": { - "property1": "string", - "property2": "string" - }, - "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" - }, - "max_deadline": "2019-08-24T14:15:22Z", - "reason": "initiator", - "resources": [ - { - "agents": [ - { - "api_version": "string", - "apps": [ - { - "command": "string", - "display_name": "string", - "external": true, - "health": "disabled", - "healthcheck": {}, - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "sharing_level": "owner", - "slug": "string", - "subdomain": true, - "subdomain_name": "string", - "url": "string" - } - ], - "architecture": "string", - "connection_timeout_seconds": 0, - "created_at": "2019-08-24T14:15:22Z", - "directory": "string", - "disconnected_at": "2019-08-24T14:15:22Z", - "display_apps": ["vscode"], - "environment_variables": { - "property1": "string", - "property2": "string" - }, - "expanded_directory": "string", - "first_connected_at": "2019-08-24T14:15:22Z", - "health": { - "healthy": false, - "reason": "agent has lost connection" - }, - "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 - } - }, - "lifecycle_state": "created", - "log_sources": [ - { - "created_at": "2019-08-24T14:15:22Z", - "display_name": "string", - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" - } - ], - "logs_length": 0, - "logs_overflowed": true, - "name": "string", - "operating_system": "string", - "ready_at": "2019-08-24T14:15:22Z", - "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", - "scripts": [ - { - "cron": "string", - "log_path": "string", - "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", - "run_on_start": true, - "run_on_stop": true, - "script": "string", - "start_blocks_login": true, - "timeout": 0 - } - ], - "started_at": "2019-08-24T14:15:22Z", - "startup_script_behavior": "blocking", - "status": "connecting", - "subsystems": ["envbox"], - "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_avatar_url": "string", - "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7", - "workspace_owner_name": "string" - }, - "name": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "organization_name": "string", - "outdated": true, - "owner_avatar_url": "string", - "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05", - "owner_name": "string", - "template_active_version_id": "b0da9c29-67d8-4c87-888c-bafe356f7f3c", - "template_allow_user_cancel_workspace_jobs": true, - "template_display_name": "string", - "template_icon": "string", - "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", - "template_name": "string", - "template_require_active_version": true, - "ttl_ms": 0, - "updated_at": "2019-08-24T14:15:22Z" - } - ] + "count": 0, + "workspaces": [ + { + "allow_renames": true, + "automatic_updates": "always", + "autostart_schedule": "string", + "created_at": "2019-08-24T14:15:22Z", + "deleting_at": "2019-08-24T14:15:22Z", + "dormant_at": "2019-08-24T14:15:22Z", + "favorite": true, + "health": { + "failing_agents": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "healthy": false + }, + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "last_used_at": "2019-08-24T14:15:22Z", + "latest_build": { + "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", + "error_code": "REQUIRED_TEMPLATE_VARIABLES", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "queue_position": 0, + "queue_size": 0, + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" + }, + "max_deadline": "2019-08-24T14:15:22Z", + "reason": "initiator", + "resources": [ + { + "agents": [ + { + "api_version": "string", + "apps": [ + { + "command": "string", + "display_name": "string", + "external": true, + "health": "disabled", + "healthcheck": {}, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "sharing_level": "owner", + "slug": "string", + "subdomain": true, + "subdomain_name": "string", + "url": "string" + } + ], + "architecture": "string", + "connection_timeout_seconds": 0, + "created_at": "2019-08-24T14:15:22Z", + "directory": "string", + "disconnected_at": "2019-08-24T14:15:22Z", + "display_apps": ["vscode"], + "environment_variables": { + "property1": "string", + "property2": "string" + }, + "expanded_directory": "string", + "first_connected_at": "2019-08-24T14:15:22Z", + "health": { + "healthy": false, + "reason": "agent has lost connection" + }, + "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 + } + }, + "lifecycle_state": "created", + "log_sources": [ + { + "created_at": "2019-08-24T14:15:22Z", + "display_name": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" + } + ], + "logs_length": 0, + "logs_overflowed": true, + "name": "string", + "operating_system": "string", + "ready_at": "2019-08-24T14:15:22Z", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", + "scripts": [ + { + "cron": "string", + "log_path": "string", + "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", + "run_on_start": true, + "run_on_stop": true, + "script": "string", + "start_blocks_login": true, + "timeout": 0 + } + ], + "started_at": "2019-08-24T14:15:22Z", + "startup_script_behavior": "blocking", + "status": "connecting", + "subsystems": ["envbox"], + "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_avatar_url": "string", + "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7", + "workspace_owner_name": "string" + }, + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "organization_name": "string", + "outdated": true, + "owner_avatar_url": "string", + "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05", + "owner_name": "string", + "template_active_version_id": "b0da9c29-67d8-4c87-888c-bafe356f7f3c", + "template_allow_user_cancel_workspace_jobs": true, + "template_display_name": "string", + "template_icon": "string", + "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", + "template_name": "string", + "template_require_active_version": true, + "ttl_ms": 0, + "updated_at": "2019-08-24T14:15:22Z" + } + ] } ``` @@ -936,183 +936,183 @@ curl -X GET http://coder-server:8080/api/v2/workspaces/{workspace} \ ```json { - "allow_renames": true, - "automatic_updates": "always", - "autostart_schedule": "string", - "created_at": "2019-08-24T14:15:22Z", - "deleting_at": "2019-08-24T14:15:22Z", - "dormant_at": "2019-08-24T14:15:22Z", - "favorite": true, - "health": { - "failing_agents": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "healthy": false - }, - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "last_used_at": "2019-08-24T14:15:22Z", - "latest_build": { - "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", - "error_code": "REQUIRED_TEMPLATE_VARIABLES", - "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "queue_position": 0, - "queue_size": 0, - "started_at": "2019-08-24T14:15:22Z", - "status": "pending", - "tags": { - "property1": "string", - "property2": "string" - }, - "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" - }, - "max_deadline": "2019-08-24T14:15:22Z", - "reason": "initiator", - "resources": [ - { - "agents": [ - { - "api_version": "string", - "apps": [ - { - "command": "string", - "display_name": "string", - "external": true, - "health": "disabled", - "healthcheck": { - "interval": 0, - "threshold": 0, - "url": "string" - }, - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "sharing_level": "owner", - "slug": "string", - "subdomain": true, - "subdomain_name": "string", - "url": "string" - } - ], - "architecture": "string", - "connection_timeout_seconds": 0, - "created_at": "2019-08-24T14:15:22Z", - "directory": "string", - "disconnected_at": "2019-08-24T14:15:22Z", - "display_apps": ["vscode"], - "environment_variables": { - "property1": "string", - "property2": "string" - }, - "expanded_directory": "string", - "first_connected_at": "2019-08-24T14:15:22Z", - "health": { - "healthy": false, - "reason": "agent has lost connection" - }, - "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 - } - }, - "lifecycle_state": "created", - "log_sources": [ - { - "created_at": "2019-08-24T14:15:22Z", - "display_name": "string", - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" - } - ], - "logs_length": 0, - "logs_overflowed": true, - "name": "string", - "operating_system": "string", - "ready_at": "2019-08-24T14:15:22Z", - "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", - "scripts": [ - { - "cron": "string", - "log_path": "string", - "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", - "run_on_start": true, - "run_on_stop": true, - "script": "string", - "start_blocks_login": true, - "timeout": 0 - } - ], - "started_at": "2019-08-24T14:15:22Z", - "startup_script_behavior": "blocking", - "status": "connecting", - "subsystems": ["envbox"], - "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_avatar_url": "string", - "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7", - "workspace_owner_name": "string" - }, - "name": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "organization_name": "string", - "outdated": true, - "owner_avatar_url": "string", - "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05", - "owner_name": "string", - "template_active_version_id": "b0da9c29-67d8-4c87-888c-bafe356f7f3c", - "template_allow_user_cancel_workspace_jobs": true, - "template_display_name": "string", - "template_icon": "string", - "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", - "template_name": "string", - "template_require_active_version": true, - "ttl_ms": 0, - "updated_at": "2019-08-24T14:15:22Z" + "allow_renames": true, + "automatic_updates": "always", + "autostart_schedule": "string", + "created_at": "2019-08-24T14:15:22Z", + "deleting_at": "2019-08-24T14:15:22Z", + "dormant_at": "2019-08-24T14:15:22Z", + "favorite": true, + "health": { + "failing_agents": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "healthy": false + }, + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "last_used_at": "2019-08-24T14:15:22Z", + "latest_build": { + "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", + "error_code": "REQUIRED_TEMPLATE_VARIABLES", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "queue_position": 0, + "queue_size": 0, + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" + }, + "max_deadline": "2019-08-24T14:15:22Z", + "reason": "initiator", + "resources": [ + { + "agents": [ + { + "api_version": "string", + "apps": [ + { + "command": "string", + "display_name": "string", + "external": true, + "health": "disabled", + "healthcheck": { + "interval": 0, + "threshold": 0, + "url": "string" + }, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "sharing_level": "owner", + "slug": "string", + "subdomain": true, + "subdomain_name": "string", + "url": "string" + } + ], + "architecture": "string", + "connection_timeout_seconds": 0, + "created_at": "2019-08-24T14:15:22Z", + "directory": "string", + "disconnected_at": "2019-08-24T14:15:22Z", + "display_apps": ["vscode"], + "environment_variables": { + "property1": "string", + "property2": "string" + }, + "expanded_directory": "string", + "first_connected_at": "2019-08-24T14:15:22Z", + "health": { + "healthy": false, + "reason": "agent has lost connection" + }, + "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 + } + }, + "lifecycle_state": "created", + "log_sources": [ + { + "created_at": "2019-08-24T14:15:22Z", + "display_name": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" + } + ], + "logs_length": 0, + "logs_overflowed": true, + "name": "string", + "operating_system": "string", + "ready_at": "2019-08-24T14:15:22Z", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", + "scripts": [ + { + "cron": "string", + "log_path": "string", + "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", + "run_on_start": true, + "run_on_stop": true, + "script": "string", + "start_blocks_login": true, + "timeout": 0 + } + ], + "started_at": "2019-08-24T14:15:22Z", + "startup_script_behavior": "blocking", + "status": "connecting", + "subsystems": ["envbox"], + "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_avatar_url": "string", + "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7", + "workspace_owner_name": "string" + }, + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "organization_name": "string", + "outdated": true, + "owner_avatar_url": "string", + "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05", + "owner_name": "string", + "template_active_version_id": "b0da9c29-67d8-4c87-888c-bafe356f7f3c", + "template_allow_user_cancel_workspace_jobs": true, + "template_display_name": "string", + "template_icon": "string", + "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", + "template_name": "string", + "template_require_active_version": true, + "ttl_ms": 0, + "updated_at": "2019-08-24T14:15:22Z" } ``` @@ -1141,7 +1141,7 @@ curl -X PATCH http://coder-server:8080/api/v2/workspaces/{workspace} \ ```json { - "name": "string" + "name": "string" } ``` @@ -1177,7 +1177,7 @@ curl -X PUT http://coder-server:8080/api/v2/workspaces/{workspace}/autostart \ ```json { - "schedule": "string" + "schedule": "string" } ``` @@ -1213,7 +1213,7 @@ curl -X PUT http://coder-server:8080/api/v2/workspaces/{workspace}/autoupdates \ ```json { - "automatic_updates": "always" + "automatic_updates": "always" } ``` @@ -1250,7 +1250,7 @@ curl -X PUT http://coder-server:8080/api/v2/workspaces/{workspace}/dormant \ ```json { - "dormant": true + "dormant": true } ``` @@ -1267,183 +1267,183 @@ curl -X PUT http://coder-server:8080/api/v2/workspaces/{workspace}/dormant \ ```json { - "allow_renames": true, - "automatic_updates": "always", - "autostart_schedule": "string", - "created_at": "2019-08-24T14:15:22Z", - "deleting_at": "2019-08-24T14:15:22Z", - "dormant_at": "2019-08-24T14:15:22Z", - "favorite": true, - "health": { - "failing_agents": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], - "healthy": false - }, - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "last_used_at": "2019-08-24T14:15:22Z", - "latest_build": { - "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", - "error_code": "REQUIRED_TEMPLATE_VARIABLES", - "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "queue_position": 0, - "queue_size": 0, - "started_at": "2019-08-24T14:15:22Z", - "status": "pending", - "tags": { - "property1": "string", - "property2": "string" - }, - "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" - }, - "max_deadline": "2019-08-24T14:15:22Z", - "reason": "initiator", - "resources": [ - { - "agents": [ - { - "api_version": "string", - "apps": [ - { - "command": "string", - "display_name": "string", - "external": true, - "health": "disabled", - "healthcheck": { - "interval": 0, - "threshold": 0, - "url": "string" - }, - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "sharing_level": "owner", - "slug": "string", - "subdomain": true, - "subdomain_name": "string", - "url": "string" - } - ], - "architecture": "string", - "connection_timeout_seconds": 0, - "created_at": "2019-08-24T14:15:22Z", - "directory": "string", - "disconnected_at": "2019-08-24T14:15:22Z", - "display_apps": ["vscode"], - "environment_variables": { - "property1": "string", - "property2": "string" - }, - "expanded_directory": "string", - "first_connected_at": "2019-08-24T14:15:22Z", - "health": { - "healthy": false, - "reason": "agent has lost connection" - }, - "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 - } - }, - "lifecycle_state": "created", - "log_sources": [ - { - "created_at": "2019-08-24T14:15:22Z", - "display_name": "string", - "icon": "string", - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", - "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" - } - ], - "logs_length": 0, - "logs_overflowed": true, - "name": "string", - "operating_system": "string", - "ready_at": "2019-08-24T14:15:22Z", - "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", - "scripts": [ - { - "cron": "string", - "log_path": "string", - "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", - "run_on_start": true, - "run_on_stop": true, - "script": "string", - "start_blocks_login": true, - "timeout": 0 - } - ], - "started_at": "2019-08-24T14:15:22Z", - "startup_script_behavior": "blocking", - "status": "connecting", - "subsystems": ["envbox"], - "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_avatar_url": "string", - "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7", - "workspace_owner_name": "string" - }, - "name": "string", - "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", - "organization_name": "string", - "outdated": true, - "owner_avatar_url": "string", - "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05", - "owner_name": "string", - "template_active_version_id": "b0da9c29-67d8-4c87-888c-bafe356f7f3c", - "template_allow_user_cancel_workspace_jobs": true, - "template_display_name": "string", - "template_icon": "string", - "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", - "template_name": "string", - "template_require_active_version": true, - "ttl_ms": 0, - "updated_at": "2019-08-24T14:15:22Z" + "allow_renames": true, + "automatic_updates": "always", + "autostart_schedule": "string", + "created_at": "2019-08-24T14:15:22Z", + "deleting_at": "2019-08-24T14:15:22Z", + "dormant_at": "2019-08-24T14:15:22Z", + "favorite": true, + "health": { + "failing_agents": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"], + "healthy": false + }, + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "last_used_at": "2019-08-24T14:15:22Z", + "latest_build": { + "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", + "error_code": "REQUIRED_TEMPLATE_VARIABLES", + "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "queue_position": 0, + "queue_size": 0, + "started_at": "2019-08-24T14:15:22Z", + "status": "pending", + "tags": { + "property1": "string", + "property2": "string" + }, + "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b" + }, + "max_deadline": "2019-08-24T14:15:22Z", + "reason": "initiator", + "resources": [ + { + "agents": [ + { + "api_version": "string", + "apps": [ + { + "command": "string", + "display_name": "string", + "external": true, + "health": "disabled", + "healthcheck": { + "interval": 0, + "threshold": 0, + "url": "string" + }, + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "sharing_level": "owner", + "slug": "string", + "subdomain": true, + "subdomain_name": "string", + "url": "string" + } + ], + "architecture": "string", + "connection_timeout_seconds": 0, + "created_at": "2019-08-24T14:15:22Z", + "directory": "string", + "disconnected_at": "2019-08-24T14:15:22Z", + "display_apps": ["vscode"], + "environment_variables": { + "property1": "string", + "property2": "string" + }, + "expanded_directory": "string", + "first_connected_at": "2019-08-24T14:15:22Z", + "health": { + "healthy": false, + "reason": "agent has lost connection" + }, + "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 + } + }, + "lifecycle_state": "created", + "log_sources": [ + { + "created_at": "2019-08-24T14:15:22Z", + "display_name": "string", + "icon": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1" + } + ], + "logs_length": 0, + "logs_overflowed": true, + "name": "string", + "operating_system": "string", + "ready_at": "2019-08-24T14:15:22Z", + "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f", + "scripts": [ + { + "cron": "string", + "log_path": "string", + "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", + "run_on_start": true, + "run_on_stop": true, + "script": "string", + "start_blocks_login": true, + "timeout": 0 + } + ], + "started_at": "2019-08-24T14:15:22Z", + "startup_script_behavior": "blocking", + "status": "connecting", + "subsystems": ["envbox"], + "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_avatar_url": "string", + "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7", + "workspace_owner_name": "string" + }, + "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", + "organization_name": "string", + "outdated": true, + "owner_avatar_url": "string", + "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05", + "owner_name": "string", + "template_active_version_id": "b0da9c29-67d8-4c87-888c-bafe356f7f3c", + "template_allow_user_cancel_workspace_jobs": true, + "template_display_name": "string", + "template_icon": "string", + "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", + "template_name": "string", + "template_require_active_version": true, + "ttl_ms": 0, + "updated_at": "2019-08-24T14:15:22Z" } ``` @@ -1473,7 +1473,7 @@ curl -X PUT http://coder-server:8080/api/v2/workspaces/{workspace}/extend \ ```json { - "deadline": "2019-08-24T14:15:22Z" + "deadline": "2019-08-24T14:15:22Z" } ``` @@ -1490,14 +1490,14 @@ curl -X PUT http://coder-server:8080/api/v2/workspaces/{workspace}/extend \ ```json { - "detail": "string", - "message": "string", - "validations": [ - { - "detail": "string", - "field": "string" - } - ] + "detail": "string", + "message": "string", + "validations": [ + { + "detail": "string", + "field": "string" + } + ] } ``` @@ -1586,7 +1586,7 @@ curl -X GET http://coder-server:8080/api/v2/workspaces/{workspace}/resolve-autos ```json { - "parameter_mismatch": true + "parameter_mismatch": true } ``` @@ -1615,7 +1615,7 @@ curl -X PUT http://coder-server:8080/api/v2/workspaces/{workspace}/ttl \ ```json { - "ttl_ms": 0 + "ttl_ms": 0 } ``` @@ -1651,8 +1651,8 @@ curl -X POST http://coder-server:8080/api/v2/workspaces/{workspace}/usage \ ```json { - "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978", - "app_name": "vscode" + "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978", + "app_name": "vscode" } ``` diff --git a/docs/templates/process-logging.md b/docs/templates/process-logging.md index 51bf613238..42577541bf 100644 --- a/docs/templates/process-logging.md +++ b/docs/templates/process-logging.md @@ -254,28 +254,28 @@ The raw logs will look something like this: ```json { - "ts": "2022-02-28T20:29:38.038452202Z", - "level": "INFO", - "msg": "exec", - "fields": { - "labels": { - "user_email": "jessie@coder.com", - "user_id": "5e876e9a-121663f01ebd1522060d5270", - "username": "jessie", - "workspace_id": "621d2e52-a6987ef6c56210058ee2593c", - "workspace_name": "main" - }, - "cmdline": "uname -a", - "event": { - "filename": "/usr/bin/uname", - "argv": ["uname", "-a"], - "truncated": false, - "pid": 920684, - "uid": 101000, - "gid": 101000, - "comm": "bash" - } - } + "ts": "2022-02-28T20:29:38.038452202Z", + "level": "INFO", + "msg": "exec", + "fields": { + "labels": { + "user_email": "jessie@coder.com", + "user_id": "5e876e9a-121663f01ebd1522060d5270", + "username": "jessie", + "workspace_id": "621d2e52-a6987ef6c56210058ee2593c", + "workspace_name": "main" + }, + "cmdline": "uname -a", + "event": { + "filename": "/usr/bin/uname", + "argv": ["uname", "-a"], + "truncated": false, + "pid": 920684, + "uid": 101000, + "gid": 101000, + "comm": "bash" + } + } } ``` diff --git a/dogfood/devcontainer.json b/dogfood/devcontainer.json index 3232c07cea..cb9689e90d 100644 --- a/dogfood/devcontainer.json +++ b/dogfood/devcontainer.json @@ -1,9 +1,9 @@ { - "name": "Develop Coder on Coder using Envbuilder", - "build": { - "dockerfile": "Dockerfile" - }, + "name": "Develop Coder on Coder using Envbuilder", + "build": { + "dockerfile": "Dockerfile" + }, - "features": {}, - "runArgs": ["--cap-add=SYS_PTRACE"] + "features": {}, + "runArgs": ["--cap-add=SYS_PTRACE"] } diff --git a/dogfood/files/etc/docker/daemon.json b/dogfood/files/etc/docker/daemon.json index 8e19eeeec1..c2cbc52c3c 100644 --- a/dogfood/files/etc/docker/daemon.json +++ b/dogfood/files/etc/docker/daemon.json @@ -1,3 +1,3 @@ { - "registry-mirrors": ["https://mirror.gcr.io"] + "registry-mirrors": ["https://mirror.gcr.io"] } diff --git a/examples/examples.gen.json b/examples/examples.gen.json index 142647f441..abf15ac7e1 100644 --- a/examples/examples.gen.json +++ b/examples/examples.gen.json @@ -1,169 +1,169 @@ // Code generated by examplegen. DO NOT EDIT. [ - { - "id": "aws-devcontainer", - "url": "", - "name": "AWS EC2 (Devcontainer)", - "description": "Provision AWS EC2 VMs with a devcontainer as Coder workspaces", - "icon": "/icon/aws.svg", - "tags": [ - "vm", - "linux", - "aws", - "persistent", - "devcontainer" - ], - "markdown": "\n# Remote Development on AWS EC2 VMs using a Devcontainer\n\nProvision AWS EC2 VMs as [Coder workspaces](https://coder.com/docs) with this example template.\n![Architecture Diagram](./architecture.svg)\n\n\u003c!-- TODO: Add screenshot --\u003e\n\n## Prerequisites\n\n### Authentication\n\nBy default, this template authenticates to AWS using the provider's default [authentication methods](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#authentication-and-configuration).\n\nThe simplest way (without making changes to the template) is via environment variables (e.g. `AWS_ACCESS_KEY_ID`) or a [credentials file](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html#cli-configure-files-format). If you are running Coder on a VM, this file must be in `/home/coder/aws/credentials`.\n\nTo use another [authentication method](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#authentication), edit the template.\n\n## Required permissions / policy\n\nThe following sample policy allows Coder to create EC2 instances and modify\ninstances provisioned by Coder:\n\n```json\n{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"VisualEditor0\",\n \"Effect\": \"Allow\",\n \"Action\": [\n \"ec2:GetDefaultCreditSpecification\",\n \"ec2:DescribeIamInstanceProfileAssociations\",\n \"ec2:DescribeTags\",\n \"ec2:DescribeInstances\",\n \"ec2:DescribeInstanceTypes\",\n \"ec2:CreateTags\",\n \"ec2:RunInstances\",\n \"ec2:DescribeInstanceCreditSpecifications\",\n \"ec2:DescribeImages\",\n \"ec2:ModifyDefaultCreditSpecification\",\n \"ec2:DescribeVolumes\"\n ],\n \"Resource\": \"*\"\n },\n {\n \"Sid\": \"CoderResources\",\n \"Effect\": \"Allow\",\n \"Action\": [\n \"ec2:DescribeInstanceAttribute\",\n \"ec2:UnmonitorInstances\",\n \"ec2:TerminateInstances\",\n \"ec2:StartInstances\",\n \"ec2:StopInstances\",\n \"ec2:DeleteTags\",\n \"ec2:MonitorInstances\",\n \"ec2:CreateTags\",\n \"ec2:RunInstances\",\n \"ec2:ModifyInstanceAttribute\",\n \"ec2:ModifyInstanceCreditSpecification\"\n ],\n \"Resource\": \"arn:aws:ec2:*:*:instance/*\",\n \"Condition\": {\n \"StringEquals\": {\n \"aws:ResourceTag/Coder_Provisioned\": \"true\"\n }\n }\n }\n ]\n}\n```\n\n## Architecture\n\nThis template provisions the following resources:\n\n- AWS Instance\n\nCoder uses `aws_ec2_instance_state` to start and stop the VM. This example template is fully persistent, meaning the full filesystem is preserved when the workspace restarts. See this [community example](https://github.com/bpmct/coder-templates/tree/main/aws-linux-ephemeral) of an ephemeral AWS instance.\n\n\u003e **Note**\n\u003e This template is designed to be a starting point! Edit the Terraform to extend the template to support your use case.\n\n## code-server\n\n`code-server` is installed via the [`code-server`](https://registry.coder.com/modules/code-server) registry module. For a list of all modules and templates pplease check [Coder Registry](https://registry.coder.com).\n" - }, - { - "id": "aws-linux", - "url": "", - "name": "AWS EC2 (Linux)", - "description": "Provision AWS EC2 VMs as Coder workspaces", - "icon": "/icon/aws.svg", - "tags": [ - "vm", - "linux", - "aws", - "persistent-vm" - ], - "markdown": "\n# Remote Development on AWS EC2 VMs (Linux)\n\nProvision AWS EC2 VMs as [Coder workspaces](https://coder.com/docs/workspaces) with this example template.\n\n\u003c!-- TODO: Add screenshot --\u003e\n\n## Prerequisites\n\n### Authentication\n\nBy default, this template authenticates to AWS using the provider's default [authentication methods](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#authentication-and-configuration).\n\nThe simplest way (without making changes to the template) is via environment variables (e.g. `AWS_ACCESS_KEY_ID`) or a [credentials file](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html#cli-configure-files-format). If you are running Coder on a VM, this file must be in `/home/coder/aws/credentials`.\n\nTo use another [authentication method](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#authentication), edit the template.\n\n## Required permissions / policy\n\nThe following sample policy allows Coder to create EC2 instances and modify\ninstances provisioned by Coder:\n\n```json\n{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"VisualEditor0\",\n \"Effect\": \"Allow\",\n \"Action\": [\n \"ec2:GetDefaultCreditSpecification\",\n \"ec2:DescribeIamInstanceProfileAssociations\",\n \"ec2:DescribeTags\",\n \"ec2:DescribeInstances\",\n \"ec2:DescribeInstanceTypes\",\n \"ec2:CreateTags\",\n \"ec2:RunInstances\",\n \"ec2:DescribeInstanceCreditSpecifications\",\n \"ec2:DescribeImages\",\n \"ec2:ModifyDefaultCreditSpecification\",\n \"ec2:DescribeVolumes\"\n ],\n \"Resource\": \"*\"\n },\n {\n \"Sid\": \"CoderResources\",\n \"Effect\": \"Allow\",\n \"Action\": [\n \"ec2:DescribeInstanceAttribute\",\n \"ec2:UnmonitorInstances\",\n \"ec2:TerminateInstances\",\n \"ec2:StartInstances\",\n \"ec2:StopInstances\",\n \"ec2:DeleteTags\",\n \"ec2:MonitorInstances\",\n \"ec2:CreateTags\",\n \"ec2:RunInstances\",\n \"ec2:ModifyInstanceAttribute\",\n \"ec2:ModifyInstanceCreditSpecification\"\n ],\n \"Resource\": \"arn:aws:ec2:*:*:instance/*\",\n \"Condition\": {\n \"StringEquals\": {\n \"aws:ResourceTag/Coder_Provisioned\": \"true\"\n }\n }\n }\n ]\n}\n```\n\n## Architecture\n\nThis template provisions the following resources:\n\n- AWS Instance\n\nCoder uses `aws_ec2_instance_state` to start and stop the VM. This example template is fully persistent, meaning the full filesystem is preserved when the workspace restarts. See this [community example](https://github.com/bpmct/coder-templates/tree/main/aws-linux-ephemeral) of an ephemeral AWS instance.\n\n\u003e **Note**\n\u003e This template is designed to be a starting point! Edit the Terraform to extend the template to support your use case.\n\n## code-server\n\n`code-server` is installed via the `startup_script` argument in the `coder_agent`\nresource block. The `coder_app` resource is defined to access `code-server` through\nthe dashboard UI over `localhost:13337`.\n" - }, - { - "id": "aws-windows", - "url": "", - "name": "AWS EC2 (Windows)", - "description": "Provision AWS EC2 VMs as Coder workspaces", - "icon": "/icon/aws.svg", - "tags": [ - "vm", - "windows", - "aws" - ], - "markdown": "\n# Remote Development on AWS EC2 VMs (Windows)\n\nProvision AWS EC2 Windows VMs as [Coder workspaces](https://coder.com/docs/workspaces) with this example template.\n\n\u003c!-- TODO: Add screenshot --\u003e\n\n## Prerequisites\n\n### Authentication\n\nBy default, this template authenticates to AWS with using the provider's default [authentication methods](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#authentication-and-configuration).\n\nThe simplest way (without making changes to the template) is via environment variables (e.g. `AWS_ACCESS_KEY_ID`) or a [credentials file](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html#cli-configure-files-format). If you are running Coder on a VM, this file must be in `/home/coder/aws/credentials`.\n\nTo use another [authentication method](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#authentication), edit the template.\n\n## Required permissions / policy\n\nThe following sample policy allows Coder to create EC2 instances and modify\ninstances provisioned by Coder:\n\n```json\n{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"VisualEditor0\",\n \"Effect\": \"Allow\",\n \"Action\": [\n \"ec2:GetDefaultCreditSpecification\",\n \"ec2:DescribeIamInstanceProfileAssociations\",\n \"ec2:DescribeTags\",\n \"ec2:DescribeInstances\",\n \"ec2:DescribeInstanceTypes\",\n \"ec2:CreateTags\",\n \"ec2:RunInstances\",\n \"ec2:DescribeInstanceCreditSpecifications\",\n \"ec2:DescribeImages\",\n \"ec2:ModifyDefaultCreditSpecification\",\n \"ec2:DescribeVolumes\"\n ],\n \"Resource\": \"*\"\n },\n {\n \"Sid\": \"CoderResources\",\n \"Effect\": \"Allow\",\n \"Action\": [\n \"ec2:DescribeInstanceAttribute\",\n \"ec2:UnmonitorInstances\",\n \"ec2:TerminateInstances\",\n \"ec2:StartInstances\",\n \"ec2:StopInstances\",\n \"ec2:DeleteTags\",\n \"ec2:MonitorInstances\",\n \"ec2:CreateTags\",\n \"ec2:RunInstances\",\n \"ec2:ModifyInstanceAttribute\",\n \"ec2:ModifyInstanceCreditSpecification\"\n ],\n \"Resource\": \"arn:aws:ec2:*:*:instance/*\",\n \"Condition\": {\n \"StringEquals\": {\n \"aws:ResourceTag/Coder_Provisioned\": \"true\"\n }\n }\n }\n ]\n}\n```\n\n## Architecture\n\nThis template provisions the following resources:\n\n- AWS Instance\n\nCoder uses `aws_ec2_instance_state` to start and stop the VM. This example template is fully persistent, meaning the full filesystem is preserved when the workspace restarts. See this [community example](https://github.com/bpmct/coder-templates/tree/main/aws-linux-ephemeral) of an ephemeral AWS instance.\n\n\u003e **Note**\n\u003e This template is designed to be a starting point! Edit the Terraform to extend the template to support your use case.\n\n## code-server\n\n`code-server` is installed via the `startup_script` argument in the `coder_agent`\nresource block. The `coder_app` resource is defined to access `code-server` through\nthe dashboard UI over `localhost:13337`.\n" - }, - { - "id": "azure-linux", - "url": "", - "name": "Azure VM (Linux)", - "description": "Provision Azure VMs as Coder workspaces", - "icon": "/icon/azure.png", - "tags": [ - "vm", - "linux", - "azure" - ], - "markdown": "\n# Remote Development on Azure VMs (Linux)\n\nProvision Azure Linux VMs as [Coder workspaces](https://coder.com/docs/workspaces) with this example template.\n\n\u003c!-- TODO: Add screenshot --\u003e\n\n## Prerequisites\n\n### Authentication\n\nThis template assumes that coderd is run in an environment that is authenticated\nwith Azure. For example, run `az login` then `az account set --subscription=\u003cid\u003e`\nto import credentials on the system and user running coderd. For other ways to\nauthenticate, [consult the Terraform docs](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs#authenticating-to-azure).\n\n## Architecture\n\nThis template provisions the following resources:\n\n- Azure VM (ephemeral, deleted on stop)\n- Managed disk (persistent, mounted to `/home/coder`)\n\nThis means, when the workspace restarts, any tools or files outside of the home directory are not persisted. To pre-bake tools into the workspace (e.g. `python3`), modify the VM image, or use a [startup script](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/script). Alternatively, individual developers can [personalize](https://coder.com/docs/dotfiles) their workspaces with dotfiles.\n\n\u003e **Note**\n\u003e This template is designed to be a starting point! Edit the Terraform to extend the template to support your use case.\n\n## code-server\n\n`code-server` is installed via the `startup_script` argument in the `coder_agent`\nresource block. The `coder_app` resource is defined to access `code-server` through\nthe dashboard UI over `localhost:13337`.\n" - }, - { - "id": "do-linux", - "url": "", - "name": "DigitalOcean Droplet (Linux)", - "description": "Provision DigitalOcean Droplets as Coder workspaces", - "icon": "/icon/do.png", - "tags": [ - "vm", - "linux", - "digitalocean" - ], - "markdown": "\n# Remote Development on DigitalOcean Droplets\n\nProvision DigitalOcean Droplets as [Coder workspaces](https://coder.com/docs/workspaces) with this example template.\n\n\u003c!-- TODO: Add screenshot --\u003e\n\n## Prerequisites\n\nTo deploy workspaces as DigitalOcean Droplets, you'll need:\n\n- DigitalOcean [personal access token (PAT)](https://docs.digitalocean.com/reference/api/create-personal-access-token/)\n\n- DigitalOcean project ID (you can get your project information via the `doctl`\n CLI by running `doctl projects list`)\n\n- Remove the following sections from the `main.tf` file if you don't want to\n associate your workspaces with a project:\n\n - `variable \"step2_do_project_id\"`\n - `resource \"digitalocean_project_resources\" \"project\"`\n\n- **Optional:** DigitalOcean SSH key ID (obtain via the `doctl` CLI by running\n `doctl compute ssh-key list`)\n\n- Note that this is only required for Fedora images to work.\n\n### Authentication\n\nThis template assumes that coderd is run in an environment that is authenticated\nwith Digital Ocean. Obtain a [Digital Ocean Personal Access\nToken](https://cloud.digitalocean.com/account/api/tokens) and set the\nenvironment variable `DIGITALOCEAN_TOKEN` to the access token before starting\ncoderd. For other ways to authenticate [consult the Terraform docs](https://registry.terraform.io/providers/digitalocean/digitalocean/latest/docs).\n\n## Architecture\n\nThis template provisions the following resources:\n\n- Azure VM (ephemeral, deleted on stop)\n- Managed disk (persistent, mounted to `/home/coder`)\n\nThis means, when the workspace restarts, any tools or files outside of the home directory are not persisted. To pre-bake tools into the workspace (e.g. `python3`), modify the VM image, or use a [startup script](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/script).\n\n\u003e **Note**\n\u003e This template is designed to be a starting point! Edit the Terraform to extend the template to support your use case.\n" - }, - { - "id": "docker", - "url": "", - "name": "Docker Containers", - "description": "Provision Docker containers as Coder workspaces", - "icon": "/icon/docker.png", - "tags": [ - "docker", - "container" - ], - "markdown": "\n# Remote Development on Docker Containers\n\nProvision Docker containers as [Coder workspaces](https://coder.com/docs/workspaces) with this example template.\n\n\u003c!-- TODO: Add screenshot --\u003e\n\n## Prerequisites\n\n### Infrastructure\n\nThe VM you run Coder on must have a running Docker socket and the `coder` user must be added to the Docker group:\n\n```sh\n# Add coder user to Docker group\nsudo adduser coder docker\n\n# Restart Coder server\nsudo systemctl restart coder\n\n# Test Docker\nsudo -u coder docker ps\n```\n\n## Architecture\n\nThis template provisions the following resources:\n\n- Docker image (built by Docker socket and kept locally)\n- Docker container pod (ephemeral)\n- Docker volume (persistent on `/home/coder`)\n\nThis means, when the workspace restarts, any tools or files outside of the home directory are not persisted. To pre-bake tools into the workspace (e.g. `python3`), modify the container image. Alternatively, individual developers can [personalize](https://coder.com/docs/dotfiles) their workspaces with dotfiles.\n\n\u003e **Note**\n\u003e This template is designed to be a starting point! Edit the Terraform to extend the template to support your use case.\n\n### Editing the image\n\nEdit the `Dockerfile` and run `coder templates push` to update workspaces.\n" - }, - { - "id": "gcp-devcontainer", - "url": "", - "name": "Google Compute Engine (Devcontainer)", - "description": "Provision a Devcontainer on Google Compute Engine instances as Coder workspaces", - "icon": "/icon/gcp.png", - "tags": [ - "vm", - "linux", - "gcp", - "devcontainer" - ], - "markdown": "\n# Remote Development in a Devcontainer on Google Compute Engine\n\n![Architecture Diagram](./architecture.svg)\n\n## Prerequisites\n\n### Authentication\n\nThis template assumes that coderd is run in an environment that is authenticated\nwith Google Cloud. For example, run `gcloud auth application-default login` to\nimport credentials on the system and user running coderd. For other ways to\nauthenticate [consult the Terraform\ndocs](https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/getting_started#adding-credentials).\n\nCoder requires a Google Cloud Service Account to provision workspaces. To create\na service account:\n\n1. Navigate to the [CGP\n console](https://console.cloud.google.com/projectselector/iam-admin/serviceaccounts/create),\n and select your Cloud project (if you have more than one project associated\n with your account)\n\n1. Provide a service account name (this name is used to generate the service\n account ID)\n\n1. Click **Create and continue**, and choose the following IAM roles to grant to\n the service account:\n\n - Compute Admin\n - Service Account User\n\n Click **Continue**.\n\n1. Click on the created key, and navigate to the **Keys** tab.\n\n1. Click **Add key** \u003e **Create new key**.\n\n1. Generate a **JSON private key**, which will be what you provide to Coder\n during the setup process.\n\n## Architecture\n\nThis template provisions the following resources:\n\n- GCP VM (persistent)\n- GCP Disk (persistent, mounted to root)\n\nCoder persists the root volume. The full filesystem is preserved when the workspace restarts.\n\n\u003e **Note**\n\u003e This template is designed to be a starting point! Edit the Terraform to extend the template to support your use case.\n\n## code-server\n\n`code-server` is installed via the [`code-server`](https://registry.coder.com/modules/code-server) registry module. Please check [Coder Registry](https://registry.coder.com) for a list of all modules and templates.\n" - }, - { - "id": "gcp-linux", - "url": "", - "name": "Google Compute Engine (Linux)", - "description": "Provision Google Compute Engine instances as Coder workspaces", - "icon": "/icon/gcp.png", - "tags": [ - "vm", - "linux", - "gcp" - ], - "markdown": "\n# Remote Development on Google Compute Engine (Linux)\n\n## Prerequisites\n\n### Authentication\n\nThis template assumes that coderd is run in an environment that is authenticated\nwith Google Cloud. For example, run `gcloud auth application-default login` to\nimport credentials on the system and user running coderd. For other ways to\nauthenticate [consult the Terraform\ndocs](https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/getting_started#adding-credentials).\n\nCoder requires a Google Cloud Service Account to provision workspaces. To create\na service account:\n\n1. Navigate to the [CGP\n console](https://console.cloud.google.com/projectselector/iam-admin/serviceaccounts/create),\n and select your Cloud project (if you have more than one project associated\n with your account)\n\n1. Provide a service account name (this name is used to generate the service\n account ID)\n\n1. Click **Create and continue**, and choose the following IAM roles to grant to\n the service account:\n\n - Compute Admin\n - Service Account User\n\n Click **Continue**.\n\n1. Click on the created key, and navigate to the **Keys** tab.\n\n1. Click **Add key** \u003e **Create new key**.\n\n1. Generate a **JSON private key**, which will be what you provide to Coder\n during the setup process.\n\n## Architecture\n\nThis template provisions the following resources:\n\n- GCP VM (ephemeral)\n- GCP Disk (persistent, mounted to root)\n\nCoder persists the root volume. The full filesystem is preserved when the workspace restarts. See this [community example](https://github.com/bpmct/coder-templates/tree/main/aws-linux-ephemeral) of an ephemeral AWS instance.\n\n\u003e **Note**\n\u003e This template is designed to be a starting point! Edit the Terraform to extend the template to support your use case.\n\n## code-server\n\n`code-server` is installed via the `startup_script` argument in the `coder_agent`\nresource block. The `coder_app` resource is defined to access `code-server` through\nthe dashboard UI over `localhost:13337`.\n" - }, - { - "id": "gcp-vm-container", - "url": "", - "name": "Google Compute Engine (VM Container)", - "description": "Provision Google Compute Engine instances as Coder workspaces", - "icon": "/icon/gcp.png", - "tags": [ - "vm-container", - "linux", - "gcp" - ], - "markdown": "\n# Remote Development on Google Compute Engine (VM Container)\n\n## Prerequisites\n\n### Authentication\n\nThis template assumes that coderd is run in an environment that is authenticated\nwith Google Cloud. For example, run `gcloud auth application-default login` to\nimport credentials on the system and user running coderd. For other ways to\nauthenticate [consult the Terraform\ndocs](https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/getting_started#adding-credentials).\n\nCoder requires a Google Cloud Service Account to provision workspaces. To create\na service account:\n\n1. Navigate to the [CGP\n console](https://console.cloud.google.com/projectselector/iam-admin/serviceaccounts/create),\n and select your Cloud project (if you have more than one project associated\n with your account)\n\n1. Provide a service account name (this name is used to generate the service\n account ID)\n\n1. Click **Create and continue**, and choose the following IAM roles to grant to\n the service account:\n\n - Compute Admin\n - Service Account User\n\n Click **Continue**.\n\n1. Click on the created key, and navigate to the **Keys** tab.\n\n1. Click **Add key** \u003e **Create new key**.\n\n1. Generate a **JSON private key**, which will be what you provide to Coder\n during the setup process.\n\n## Architecture\n\nThis template provisions the following resources:\n\n- GCP VM (ephemeral, deleted on stop)\n - Container in VM\n- Managed disk (persistent, mounted to `/home/coder` in container)\n\nThis means, when the workspace restarts, any tools or files outside of the home directory are not persisted. To pre-bake tools into the workspace (e.g. `python3`), modify the container image, or use a [startup script](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/script).\n\n\u003e **Note**\n\u003e This template is designed to be a starting point! Edit the Terraform to extend the template to support your use case.\n\n## code-server\n\n`code-server` is installed via the `startup_script` argument in the `coder_agent`\nresource block. The `coder_app` resource is defined to access `code-server` through\nthe dashboard UI over `localhost:13337`.\n" - }, - { - "id": "gcp-windows", - "url": "", - "name": "Google Compute Engine (Windows)", - "description": "Provision Google Compute Engine instances as Coder workspaces", - "icon": "/icon/gcp.png", - "tags": [ - "vm", - "windows", - "gcp" - ], - "markdown": "\n# Remote Development on Google Compute Engine (Windows)\n\n## Prerequisites\n\n### Authentication\n\nThis template assumes that coderd is run in an environment that is authenticated\nwith Google Cloud. For example, run `gcloud auth application-default login` to\nimport credentials on the system and user running coderd. For other ways to\nauthenticate [consult the Terraform\ndocs](https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/getting_started#adding-credentials).\n\nCoder requires a Google Cloud Service Account to provision workspaces. To create\na service account:\n\n1. Navigate to the [CGP\n console](https://console.cloud.google.com/projectselector/iam-admin/serviceaccounts/create),\n and select your Cloud project (if you have more than one project associated\n with your account)\n\n1. Provide a service account name (this name is used to generate the service\n account ID)\n\n1. Click **Create and continue**, and choose the following IAM roles to grant to\n the service account:\n\n - Compute Admin\n - Service Account User\n\n Click **Continue**.\n\n1. Click on the created key, and navigate to the **Keys** tab.\n\n1. Click **Add key** \u003e **Create new key**.\n\n1. Generate a **JSON private key**, which will be what you provide to Coder\n during the setup process.\n\n## Architecture\n\nThis template provisions the following resources:\n\n- GCP VM (ephemeral)\n- GCP Disk (persistent, mounted to root)\n\nCoder persists the root volume. The full filesystem is preserved when the workspace restarts. See this [community example](https://github.com/bpmct/coder-templates/tree/main/aws-linux-ephemeral) of an ephemeral AWS instance.\n\n\u003e **Note**\n\u003e This template is designed to be a starting point! Edit the Terraform to extend the template to support your use case.\n\n## code-server\n\n`code-server` is installed via the `startup_script` argument in the `coder_agent`\nresource block. The `coder_app` resource is defined to access `code-server` through\nthe dashboard UI over `localhost:13337`.\n" - }, - { - "id": "kubernetes", - "url": "", - "name": "Kubernetes (Deployment)", - "description": "Provision Kubernetes Deployments as Coder workspaces", - "icon": "/icon/k8s.png", - "tags": [ - "kubernetes", - "container" - ], - "markdown": "\n# Remote Development on Kubernetes Pods\n\nProvision Kubernetes Pods as [Coder workspaces](https://coder.com/docs/workspaces) with this example template.\n\n\u003c!-- TODO: Add screenshot --\u003e\n\n## Prerequisites\n\n### Infrastructure\n\n**Cluster**: This template requires an existing Kubernetes cluster\n\n**Container Image**: This template uses the [codercom/enterprise-base:ubuntu image](https://github.com/coder/enterprise-images/tree/main/images/base) with some dev tools preinstalled. To add additional tools, extend this image or build it yourself.\n\n### Authentication\n\nThis template authenticates using a `~/.kube/config`, if present on the server, or via built-in authentication if the Coder provisioner is running on Kubernetes with an authorized ServiceAccount. To use another [authentication method](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs#authentication), edit the template.\n\n## Architecture\n\nThis template provisions the following resources:\n\n- Kubernetes pod (ephemeral)\n- Kubernetes persistent volume claim (persistent on `/home/coder`)\n\nThis means, when the workspace restarts, any tools or files outside of the home directory are not persisted. To pre-bake tools into the workspace (e.g. `python3`), modify the container image. Alternatively, individual developers can [personalize](https://coder.com/docs/dotfiles) their workspaces with dotfiles.\n\n\u003e **Note**\n\u003e This template is designed to be a starting point! Edit the Terraform to extend the template to support your use case.\n" - }, - { - "id": "nomad-docker", - "url": "", - "name": "Nomad", - "description": "Provision Nomad Jobs as Coder workspaces", - "icon": "/icon/nomad.svg", - "tags": [ - "nomad", - "container" - ], - "markdown": "\n# Remote Development on Nomad\n\nProvision Nomad Jobs as [Coder workspaces](https://coder.com/docs/workspaces) with this example template. This example shows how to use Nomad service tasks to be used as a development environment using docker and host csi volumes.\n\n\u003c!-- TODO: Add screenshot --\u003e\n\n\u003e **Note**\n\u003e This template is designed to be a starting point! Edit the Terraform to extend the template to support your use case.\n\n## Prerequisites\n\n- [Nomad](https://www.nomadproject.io/downloads)\n- [Docker](https://docs.docker.com/get-docker/)\n\n## Setup\n\n### 1. Start the CSI Host Volume Plugin\n\nThe CSI Host Volume plugin is used to mount host volumes into Nomad tasks. This is useful for development environments where you want to mount persistent volumes into your container workspace.\n\n1. Login to the Nomad server using SSH.\n\n2. Append the following stanza to your Nomad server configuration file and restart the nomad service.\n\n ```hcl\n plugin \"docker\" {\n config {\n allow_privileged = true\n }\n }\n ```\n\n ```shell\n sudo systemctl restart nomad\n ```\n\n3. Create a file `hostpath.nomad` with following content:\n\n ```hcl\n job \"hostpath-csi-plugin\" {\n datacenters = [\"dc1\"]\n type = \"system\"\n\n group \"csi\" {\n task \"plugin\" {\n driver = \"docker\"\n\n config {\n image = \"registry.k8s.io/sig-storage/hostpathplugin:v1.10.0\"\n\n args = [\n \"--drivername=csi-hostpath\",\n \"--v=5\",\n \"--endpoint=${CSI_ENDPOINT}\",\n \"--nodeid=node-${NOMAD_ALLOC_INDEX}\",\n ]\n\n privileged = true\n }\n\n csi_plugin {\n id = \"hostpath\"\n type = \"monolith\"\n mount_dir = \"/csi\"\n }\n\n resources {\n cpu = 256\n memory = 128\n }\n }\n }\n }\n ```\n\n4. Run the job:\n\n ```shell\n nomad job run hostpath.nomad\n ```\n\n### 2. Setup the Nomad Template\n\n1. Create the template by running the following command:\n\n ```shell\n coder template init nomad-docker\n cd nomad-docker\n coder template push\n ```\n\n2. Set up Nomad server address and optional authentication:\n\n3. Create a new workspace and start developing.\n" - }, - { - "id": "scratch", - "url": "", - "name": "Scratch", - "description": "A minimal starter template for Coder", - "icon": "/emojis/1f4e6.png", - "tags": [], - "markdown": "\n# A minimal Scaffolding for a Coder Template\n\nUse this starter template as a basis to create your own unique template from scratch.\n" - } + { + "id": "aws-devcontainer", + "url": "", + "name": "AWS EC2 (Devcontainer)", + "description": "Provision AWS EC2 VMs with a devcontainer as Coder workspaces", + "icon": "/icon/aws.svg", + "tags": [ + "vm", + "linux", + "aws", + "persistent", + "devcontainer" + ], + "markdown": "\n# Remote Development on AWS EC2 VMs using a Devcontainer\n\nProvision AWS EC2 VMs as [Coder workspaces](https://coder.com/docs) with this example template.\n![Architecture Diagram](./architecture.svg)\n\n\u003c!-- TODO: Add screenshot --\u003e\n\n## Prerequisites\n\n### Authentication\n\nBy default, this template authenticates to AWS using the provider's default [authentication methods](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#authentication-and-configuration).\n\nThe simplest way (without making changes to the template) is via environment variables (e.g. `AWS_ACCESS_KEY_ID`) or a [credentials file](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html#cli-configure-files-format). If you are running Coder on a VM, this file must be in `/home/coder/aws/credentials`.\n\nTo use another [authentication method](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#authentication), edit the template.\n\n## Required permissions / policy\n\nThe following sample policy allows Coder to create EC2 instances and modify\ninstances provisioned by Coder:\n\n```json\n{\n\t\"Version\": \"2012-10-17\",\n\t\"Statement\": [\n\t\t{\n\t\t\t\"Sid\": \"VisualEditor0\",\n\t\t\t\"Effect\": \"Allow\",\n\t\t\t\"Action\": [\n\t\t\t\t\"ec2:GetDefaultCreditSpecification\",\n\t\t\t\t\"ec2:DescribeIamInstanceProfileAssociations\",\n\t\t\t\t\"ec2:DescribeTags\",\n\t\t\t\t\"ec2:DescribeInstances\",\n\t\t\t\t\"ec2:DescribeInstanceTypes\",\n\t\t\t\t\"ec2:CreateTags\",\n\t\t\t\t\"ec2:RunInstances\",\n\t\t\t\t\"ec2:DescribeInstanceCreditSpecifications\",\n\t\t\t\t\"ec2:DescribeImages\",\n\t\t\t\t\"ec2:ModifyDefaultCreditSpecification\",\n\t\t\t\t\"ec2:DescribeVolumes\"\n\t\t\t],\n\t\t\t\"Resource\": \"*\"\n\t\t},\n\t\t{\n\t\t\t\"Sid\": \"CoderResources\",\n\t\t\t\"Effect\": \"Allow\",\n\t\t\t\"Action\": [\n\t\t\t\t\"ec2:DescribeInstanceAttribute\",\n\t\t\t\t\"ec2:UnmonitorInstances\",\n\t\t\t\t\"ec2:TerminateInstances\",\n\t\t\t\t\"ec2:StartInstances\",\n\t\t\t\t\"ec2:StopInstances\",\n\t\t\t\t\"ec2:DeleteTags\",\n\t\t\t\t\"ec2:MonitorInstances\",\n\t\t\t\t\"ec2:CreateTags\",\n\t\t\t\t\"ec2:RunInstances\",\n\t\t\t\t\"ec2:ModifyInstanceAttribute\",\n\t\t\t\t\"ec2:ModifyInstanceCreditSpecification\"\n\t\t\t],\n\t\t\t\"Resource\": \"arn:aws:ec2:*:*:instance/*\",\n\t\t\t\"Condition\": {\n\t\t\t\t\"StringEquals\": {\n\t\t\t\t\t\"aws:ResourceTag/Coder_Provisioned\": \"true\"\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t]\n}\n```\n\n## Architecture\n\nThis template provisions the following resources:\n\n- AWS Instance\n\nCoder uses `aws_ec2_instance_state` to start and stop the VM. This example template is fully persistent, meaning the full filesystem is preserved when the workspace restarts. See this [community example](https://github.com/bpmct/coder-templates/tree/main/aws-linux-ephemeral) of an ephemeral AWS instance.\n\n\u003e **Note**\n\u003e This template is designed to be a starting point! Edit the Terraform to extend the template to support your use case.\n\n## code-server\n\n`code-server` is installed via the [`code-server`](https://registry.coder.com/modules/code-server) registry module. For a list of all modules and templates pplease check [Coder Registry](https://registry.coder.com).\n" + }, + { + "id": "aws-linux", + "url": "", + "name": "AWS EC2 (Linux)", + "description": "Provision AWS EC2 VMs as Coder workspaces", + "icon": "/icon/aws.svg", + "tags": [ + "vm", + "linux", + "aws", + "persistent-vm" + ], + "markdown": "\n# Remote Development on AWS EC2 VMs (Linux)\n\nProvision AWS EC2 VMs as [Coder workspaces](https://coder.com/docs/workspaces) with this example template.\n\n\u003c!-- TODO: Add screenshot --\u003e\n\n## Prerequisites\n\n### Authentication\n\nBy default, this template authenticates to AWS using the provider's default [authentication methods](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#authentication-and-configuration).\n\nThe simplest way (without making changes to the template) is via environment variables (e.g. `AWS_ACCESS_KEY_ID`) or a [credentials file](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html#cli-configure-files-format). If you are running Coder on a VM, this file must be in `/home/coder/aws/credentials`.\n\nTo use another [authentication method](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#authentication), edit the template.\n\n## Required permissions / policy\n\nThe following sample policy allows Coder to create EC2 instances and modify\ninstances provisioned by Coder:\n\n```json\n{\n\t\"Version\": \"2012-10-17\",\n\t\"Statement\": [\n\t\t{\n\t\t\t\"Sid\": \"VisualEditor0\",\n\t\t\t\"Effect\": \"Allow\",\n\t\t\t\"Action\": [\n\t\t\t\t\"ec2:GetDefaultCreditSpecification\",\n\t\t\t\t\"ec2:DescribeIamInstanceProfileAssociations\",\n\t\t\t\t\"ec2:DescribeTags\",\n\t\t\t\t\"ec2:DescribeInstances\",\n\t\t\t\t\"ec2:DescribeInstanceTypes\",\n\t\t\t\t\"ec2:CreateTags\",\n\t\t\t\t\"ec2:RunInstances\",\n\t\t\t\t\"ec2:DescribeInstanceCreditSpecifications\",\n\t\t\t\t\"ec2:DescribeImages\",\n\t\t\t\t\"ec2:ModifyDefaultCreditSpecification\",\n\t\t\t\t\"ec2:DescribeVolumes\"\n\t\t\t],\n\t\t\t\"Resource\": \"*\"\n\t\t},\n\t\t{\n\t\t\t\"Sid\": \"CoderResources\",\n\t\t\t\"Effect\": \"Allow\",\n\t\t\t\"Action\": [\n\t\t\t\t\"ec2:DescribeInstanceAttribute\",\n\t\t\t\t\"ec2:UnmonitorInstances\",\n\t\t\t\t\"ec2:TerminateInstances\",\n\t\t\t\t\"ec2:StartInstances\",\n\t\t\t\t\"ec2:StopInstances\",\n\t\t\t\t\"ec2:DeleteTags\",\n\t\t\t\t\"ec2:MonitorInstances\",\n\t\t\t\t\"ec2:CreateTags\",\n\t\t\t\t\"ec2:RunInstances\",\n\t\t\t\t\"ec2:ModifyInstanceAttribute\",\n\t\t\t\t\"ec2:ModifyInstanceCreditSpecification\"\n\t\t\t],\n\t\t\t\"Resource\": \"arn:aws:ec2:*:*:instance/*\",\n\t\t\t\"Condition\": {\n\t\t\t\t\"StringEquals\": {\n\t\t\t\t\t\"aws:ResourceTag/Coder_Provisioned\": \"true\"\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t]\n}\n```\n\n## Architecture\n\nThis template provisions the following resources:\n\n- AWS Instance\n\nCoder uses `aws_ec2_instance_state` to start and stop the VM. This example template is fully persistent, meaning the full filesystem is preserved when the workspace restarts. See this [community example](https://github.com/bpmct/coder-templates/tree/main/aws-linux-ephemeral) of an ephemeral AWS instance.\n\n\u003e **Note**\n\u003e This template is designed to be a starting point! Edit the Terraform to extend the template to support your use case.\n\n## code-server\n\n`code-server` is installed via the `startup_script` argument in the `coder_agent`\nresource block. The `coder_app` resource is defined to access `code-server` through\nthe dashboard UI over `localhost:13337`.\n" + }, + { + "id": "aws-windows", + "url": "", + "name": "AWS EC2 (Windows)", + "description": "Provision AWS EC2 VMs as Coder workspaces", + "icon": "/icon/aws.svg", + "tags": [ + "vm", + "windows", + "aws" + ], + "markdown": "\n# Remote Development on AWS EC2 VMs (Windows)\n\nProvision AWS EC2 Windows VMs as [Coder workspaces](https://coder.com/docs/workspaces) with this example template.\n\n\u003c!-- TODO: Add screenshot --\u003e\n\n## Prerequisites\n\n### Authentication\n\nBy default, this template authenticates to AWS with using the provider's default [authentication methods](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#authentication-and-configuration).\n\nThe simplest way (without making changes to the template) is via environment variables (e.g. `AWS_ACCESS_KEY_ID`) or a [credentials file](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html#cli-configure-files-format). If you are running Coder on a VM, this file must be in `/home/coder/aws/credentials`.\n\nTo use another [authentication method](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#authentication), edit the template.\n\n## Required permissions / policy\n\nThe following sample policy allows Coder to create EC2 instances and modify\ninstances provisioned by Coder:\n\n```json\n{\n\t\"Version\": \"2012-10-17\",\n\t\"Statement\": [\n\t\t{\n\t\t\t\"Sid\": \"VisualEditor0\",\n\t\t\t\"Effect\": \"Allow\",\n\t\t\t\"Action\": [\n\t\t\t\t\"ec2:GetDefaultCreditSpecification\",\n\t\t\t\t\"ec2:DescribeIamInstanceProfileAssociations\",\n\t\t\t\t\"ec2:DescribeTags\",\n\t\t\t\t\"ec2:DescribeInstances\",\n\t\t\t\t\"ec2:DescribeInstanceTypes\",\n\t\t\t\t\"ec2:CreateTags\",\n\t\t\t\t\"ec2:RunInstances\",\n\t\t\t\t\"ec2:DescribeInstanceCreditSpecifications\",\n\t\t\t\t\"ec2:DescribeImages\",\n\t\t\t\t\"ec2:ModifyDefaultCreditSpecification\",\n\t\t\t\t\"ec2:DescribeVolumes\"\n\t\t\t],\n\t\t\t\"Resource\": \"*\"\n\t\t},\n\t\t{\n\t\t\t\"Sid\": \"CoderResources\",\n\t\t\t\"Effect\": \"Allow\",\n\t\t\t\"Action\": [\n\t\t\t\t\"ec2:DescribeInstanceAttribute\",\n\t\t\t\t\"ec2:UnmonitorInstances\",\n\t\t\t\t\"ec2:TerminateInstances\",\n\t\t\t\t\"ec2:StartInstances\",\n\t\t\t\t\"ec2:StopInstances\",\n\t\t\t\t\"ec2:DeleteTags\",\n\t\t\t\t\"ec2:MonitorInstances\",\n\t\t\t\t\"ec2:CreateTags\",\n\t\t\t\t\"ec2:RunInstances\",\n\t\t\t\t\"ec2:ModifyInstanceAttribute\",\n\t\t\t\t\"ec2:ModifyInstanceCreditSpecification\"\n\t\t\t],\n\t\t\t\"Resource\": \"arn:aws:ec2:*:*:instance/*\",\n\t\t\t\"Condition\": {\n\t\t\t\t\"StringEquals\": {\n\t\t\t\t\t\"aws:ResourceTag/Coder_Provisioned\": \"true\"\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t]\n}\n```\n\n## Architecture\n\nThis template provisions the following resources:\n\n- AWS Instance\n\nCoder uses `aws_ec2_instance_state` to start and stop the VM. This example template is fully persistent, meaning the full filesystem is preserved when the workspace restarts. See this [community example](https://github.com/bpmct/coder-templates/tree/main/aws-linux-ephemeral) of an ephemeral AWS instance.\n\n\u003e **Note**\n\u003e This template is designed to be a starting point! Edit the Terraform to extend the template to support your use case.\n\n## code-server\n\n`code-server` is installed via the `startup_script` argument in the `coder_agent`\nresource block. The `coder_app` resource is defined to access `code-server` through\nthe dashboard UI over `localhost:13337`.\n" + }, + { + "id": "azure-linux", + "url": "", + "name": "Azure VM (Linux)", + "description": "Provision Azure VMs as Coder workspaces", + "icon": "/icon/azure.png", + "tags": [ + "vm", + "linux", + "azure" + ], + "markdown": "\n# Remote Development on Azure VMs (Linux)\n\nProvision Azure Linux VMs as [Coder workspaces](https://coder.com/docs/workspaces) with this example template.\n\n\u003c!-- TODO: Add screenshot --\u003e\n\n## Prerequisites\n\n### Authentication\n\nThis template assumes that coderd is run in an environment that is authenticated\nwith Azure. For example, run `az login` then `az account set --subscription=\u003cid\u003e`\nto import credentials on the system and user running coderd. For other ways to\nauthenticate, [consult the Terraform docs](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs#authenticating-to-azure).\n\n## Architecture\n\nThis template provisions the following resources:\n\n- Azure VM (ephemeral, deleted on stop)\n- Managed disk (persistent, mounted to `/home/coder`)\n\nThis means, when the workspace restarts, any tools or files outside of the home directory are not persisted. To pre-bake tools into the workspace (e.g. `python3`), modify the VM image, or use a [startup script](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/script). Alternatively, individual developers can [personalize](https://coder.com/docs/dotfiles) their workspaces with dotfiles.\n\n\u003e **Note**\n\u003e This template is designed to be a starting point! Edit the Terraform to extend the template to support your use case.\n\n## code-server\n\n`code-server` is installed via the `startup_script` argument in the `coder_agent`\nresource block. The `coder_app` resource is defined to access `code-server` through\nthe dashboard UI over `localhost:13337`.\n" + }, + { + "id": "do-linux", + "url": "", + "name": "DigitalOcean Droplet (Linux)", + "description": "Provision DigitalOcean Droplets as Coder workspaces", + "icon": "/icon/do.png", + "tags": [ + "vm", + "linux", + "digitalocean" + ], + "markdown": "\n# Remote Development on DigitalOcean Droplets\n\nProvision DigitalOcean Droplets as [Coder workspaces](https://coder.com/docs/workspaces) with this example template.\n\n\u003c!-- TODO: Add screenshot --\u003e\n\n## Prerequisites\n\nTo deploy workspaces as DigitalOcean Droplets, you'll need:\n\n- DigitalOcean [personal access token (PAT)](https://docs.digitalocean.com/reference/api/create-personal-access-token/)\n\n- DigitalOcean project ID (you can get your project information via the `doctl`\n CLI by running `doctl projects list`)\n\n- Remove the following sections from the `main.tf` file if you don't want to\n associate your workspaces with a project:\n\n - `variable \"step2_do_project_id\"`\n - `resource \"digitalocean_project_resources\" \"project\"`\n\n- **Optional:** DigitalOcean SSH key ID (obtain via the `doctl` CLI by running\n `doctl compute ssh-key list`)\n\n- Note that this is only required for Fedora images to work.\n\n### Authentication\n\nThis template assumes that coderd is run in an environment that is authenticated\nwith Digital Ocean. Obtain a [Digital Ocean Personal Access\nToken](https://cloud.digitalocean.com/account/api/tokens) and set the\nenvironment variable `DIGITALOCEAN_TOKEN` to the access token before starting\ncoderd. For other ways to authenticate [consult the Terraform docs](https://registry.terraform.io/providers/digitalocean/digitalocean/latest/docs).\n\n## Architecture\n\nThis template provisions the following resources:\n\n- Azure VM (ephemeral, deleted on stop)\n- Managed disk (persistent, mounted to `/home/coder`)\n\nThis means, when the workspace restarts, any tools or files outside of the home directory are not persisted. To pre-bake tools into the workspace (e.g. `python3`), modify the VM image, or use a [startup script](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/script).\n\n\u003e **Note**\n\u003e This template is designed to be a starting point! Edit the Terraform to extend the template to support your use case.\n" + }, + { + "id": "docker", + "url": "", + "name": "Docker Containers", + "description": "Provision Docker containers as Coder workspaces", + "icon": "/icon/docker.png", + "tags": [ + "docker", + "container" + ], + "markdown": "\n# Remote Development on Docker Containers\n\nProvision Docker containers as [Coder workspaces](https://coder.com/docs/workspaces) with this example template.\n\n\u003c!-- TODO: Add screenshot --\u003e\n\n## Prerequisites\n\n### Infrastructure\n\nThe VM you run Coder on must have a running Docker socket and the `coder` user must be added to the Docker group:\n\n```sh\n# Add coder user to Docker group\nsudo adduser coder docker\n\n# Restart Coder server\nsudo systemctl restart coder\n\n# Test Docker\nsudo -u coder docker ps\n```\n\n## Architecture\n\nThis template provisions the following resources:\n\n- Docker image (built by Docker socket and kept locally)\n- Docker container pod (ephemeral)\n- Docker volume (persistent on `/home/coder`)\n\nThis means, when the workspace restarts, any tools or files outside of the home directory are not persisted. To pre-bake tools into the workspace (e.g. `python3`), modify the container image. Alternatively, individual developers can [personalize](https://coder.com/docs/dotfiles) their workspaces with dotfiles.\n\n\u003e **Note**\n\u003e This template is designed to be a starting point! Edit the Terraform to extend the template to support your use case.\n\n### Editing the image\n\nEdit the `Dockerfile` and run `coder templates push` to update workspaces.\n" + }, + { + "id": "gcp-devcontainer", + "url": "", + "name": "Google Compute Engine (Devcontainer)", + "description": "Provision a Devcontainer on Google Compute Engine instances as Coder workspaces", + "icon": "/icon/gcp.png", + "tags": [ + "vm", + "linux", + "gcp", + "devcontainer" + ], + "markdown": "\n# Remote Development in a Devcontainer on Google Compute Engine\n\n![Architecture Diagram](./architecture.svg)\n\n## Prerequisites\n\n### Authentication\n\nThis template assumes that coderd is run in an environment that is authenticated\nwith Google Cloud. For example, run `gcloud auth application-default login` to\nimport credentials on the system and user running coderd. For other ways to\nauthenticate [consult the Terraform\ndocs](https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/getting_started#adding-credentials).\n\nCoder requires a Google Cloud Service Account to provision workspaces. To create\na service account:\n\n1. Navigate to the [CGP\n console](https://console.cloud.google.com/projectselector/iam-admin/serviceaccounts/create),\n and select your Cloud project (if you have more than one project associated\n with your account)\n\n1. Provide a service account name (this name is used to generate the service\n account ID)\n\n1. Click **Create and continue**, and choose the following IAM roles to grant to\n the service account:\n\n - Compute Admin\n - Service Account User\n\n Click **Continue**.\n\n1. Click on the created key, and navigate to the **Keys** tab.\n\n1. Click **Add key** \u003e **Create new key**.\n\n1. Generate a **JSON private key**, which will be what you provide to Coder\n during the setup process.\n\n## Architecture\n\nThis template provisions the following resources:\n\n- GCP VM (persistent)\n- GCP Disk (persistent, mounted to root)\n\nCoder persists the root volume. The full filesystem is preserved when the workspace restarts.\n\n\u003e **Note**\n\u003e This template is designed to be a starting point! Edit the Terraform to extend the template to support your use case.\n\n## code-server\n\n`code-server` is installed via the [`code-server`](https://registry.coder.com/modules/code-server) registry module. Please check [Coder Registry](https://registry.coder.com) for a list of all modules and templates.\n" + }, + { + "id": "gcp-linux", + "url": "", + "name": "Google Compute Engine (Linux)", + "description": "Provision Google Compute Engine instances as Coder workspaces", + "icon": "/icon/gcp.png", + "tags": [ + "vm", + "linux", + "gcp" + ], + "markdown": "\n# Remote Development on Google Compute Engine (Linux)\n\n## Prerequisites\n\n### Authentication\n\nThis template assumes that coderd is run in an environment that is authenticated\nwith Google Cloud. For example, run `gcloud auth application-default login` to\nimport credentials on the system and user running coderd. For other ways to\nauthenticate [consult the Terraform\ndocs](https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/getting_started#adding-credentials).\n\nCoder requires a Google Cloud Service Account to provision workspaces. To create\na service account:\n\n1. Navigate to the [CGP\n console](https://console.cloud.google.com/projectselector/iam-admin/serviceaccounts/create),\n and select your Cloud project (if you have more than one project associated\n with your account)\n\n1. Provide a service account name (this name is used to generate the service\n account ID)\n\n1. Click **Create and continue**, and choose the following IAM roles to grant to\n the service account:\n\n - Compute Admin\n - Service Account User\n\n Click **Continue**.\n\n1. Click on the created key, and navigate to the **Keys** tab.\n\n1. Click **Add key** \u003e **Create new key**.\n\n1. Generate a **JSON private key**, which will be what you provide to Coder\n during the setup process.\n\n## Architecture\n\nThis template provisions the following resources:\n\n- GCP VM (ephemeral)\n- GCP Disk (persistent, mounted to root)\n\nCoder persists the root volume. The full filesystem is preserved when the workspace restarts. See this [community example](https://github.com/bpmct/coder-templates/tree/main/aws-linux-ephemeral) of an ephemeral AWS instance.\n\n\u003e **Note**\n\u003e This template is designed to be a starting point! Edit the Terraform to extend the template to support your use case.\n\n## code-server\n\n`code-server` is installed via the `startup_script` argument in the `coder_agent`\nresource block. The `coder_app` resource is defined to access `code-server` through\nthe dashboard UI over `localhost:13337`.\n" + }, + { + "id": "gcp-vm-container", + "url": "", + "name": "Google Compute Engine (VM Container)", + "description": "Provision Google Compute Engine instances as Coder workspaces", + "icon": "/icon/gcp.png", + "tags": [ + "vm-container", + "linux", + "gcp" + ], + "markdown": "\n# Remote Development on Google Compute Engine (VM Container)\n\n## Prerequisites\n\n### Authentication\n\nThis template assumes that coderd is run in an environment that is authenticated\nwith Google Cloud. For example, run `gcloud auth application-default login` to\nimport credentials on the system and user running coderd. For other ways to\nauthenticate [consult the Terraform\ndocs](https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/getting_started#adding-credentials).\n\nCoder requires a Google Cloud Service Account to provision workspaces. To create\na service account:\n\n1. Navigate to the [CGP\n console](https://console.cloud.google.com/projectselector/iam-admin/serviceaccounts/create),\n and select your Cloud project (if you have more than one project associated\n with your account)\n\n1. Provide a service account name (this name is used to generate the service\n account ID)\n\n1. Click **Create and continue**, and choose the following IAM roles to grant to\n the service account:\n\n - Compute Admin\n - Service Account User\n\n Click **Continue**.\n\n1. Click on the created key, and navigate to the **Keys** tab.\n\n1. Click **Add key** \u003e **Create new key**.\n\n1. Generate a **JSON private key**, which will be what you provide to Coder\n during the setup process.\n\n## Architecture\n\nThis template provisions the following resources:\n\n- GCP VM (ephemeral, deleted on stop)\n - Container in VM\n- Managed disk (persistent, mounted to `/home/coder` in container)\n\nThis means, when the workspace restarts, any tools or files outside of the home directory are not persisted. To pre-bake tools into the workspace (e.g. `python3`), modify the container image, or use a [startup script](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/script).\n\n\u003e **Note**\n\u003e This template is designed to be a starting point! Edit the Terraform to extend the template to support your use case.\n\n## code-server\n\n`code-server` is installed via the `startup_script` argument in the `coder_agent`\nresource block. The `coder_app` resource is defined to access `code-server` through\nthe dashboard UI over `localhost:13337`.\n" + }, + { + "id": "gcp-windows", + "url": "", + "name": "Google Compute Engine (Windows)", + "description": "Provision Google Compute Engine instances as Coder workspaces", + "icon": "/icon/gcp.png", + "tags": [ + "vm", + "windows", + "gcp" + ], + "markdown": "\n# Remote Development on Google Compute Engine (Windows)\n\n## Prerequisites\n\n### Authentication\n\nThis template assumes that coderd is run in an environment that is authenticated\nwith Google Cloud. For example, run `gcloud auth application-default login` to\nimport credentials on the system and user running coderd. For other ways to\nauthenticate [consult the Terraform\ndocs](https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/getting_started#adding-credentials).\n\nCoder requires a Google Cloud Service Account to provision workspaces. To create\na service account:\n\n1. Navigate to the [CGP\n console](https://console.cloud.google.com/projectselector/iam-admin/serviceaccounts/create),\n and select your Cloud project (if you have more than one project associated\n with your account)\n\n1. Provide a service account name (this name is used to generate the service\n account ID)\n\n1. Click **Create and continue**, and choose the following IAM roles to grant to\n the service account:\n\n - Compute Admin\n - Service Account User\n\n Click **Continue**.\n\n1. Click on the created key, and navigate to the **Keys** tab.\n\n1. Click **Add key** \u003e **Create new key**.\n\n1. Generate a **JSON private key**, which will be what you provide to Coder\n during the setup process.\n\n## Architecture\n\nThis template provisions the following resources:\n\n- GCP VM (ephemeral)\n- GCP Disk (persistent, mounted to root)\n\nCoder persists the root volume. The full filesystem is preserved when the workspace restarts. See this [community example](https://github.com/bpmct/coder-templates/tree/main/aws-linux-ephemeral) of an ephemeral AWS instance.\n\n\u003e **Note**\n\u003e This template is designed to be a starting point! Edit the Terraform to extend the template to support your use case.\n\n## code-server\n\n`code-server` is installed via the `startup_script` argument in the `coder_agent`\nresource block. The `coder_app` resource is defined to access `code-server` through\nthe dashboard UI over `localhost:13337`.\n" + }, + { + "id": "kubernetes", + "url": "", + "name": "Kubernetes (Deployment)", + "description": "Provision Kubernetes Deployments as Coder workspaces", + "icon": "/icon/k8s.png", + "tags": [ + "kubernetes", + "container" + ], + "markdown": "\n# Remote Development on Kubernetes Pods\n\nProvision Kubernetes Pods as [Coder workspaces](https://coder.com/docs/workspaces) with this example template.\n\n\u003c!-- TODO: Add screenshot --\u003e\n\n## Prerequisites\n\n### Infrastructure\n\n**Cluster**: This template requires an existing Kubernetes cluster\n\n**Container Image**: This template uses the [codercom/enterprise-base:ubuntu image](https://github.com/coder/enterprise-images/tree/main/images/base) with some dev tools preinstalled. To add additional tools, extend this image or build it yourself.\n\n### Authentication\n\nThis template authenticates using a `~/.kube/config`, if present on the server, or via built-in authentication if the Coder provisioner is running on Kubernetes with an authorized ServiceAccount. To use another [authentication method](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs#authentication), edit the template.\n\n## Architecture\n\nThis template provisions the following resources:\n\n- Kubernetes pod (ephemeral)\n- Kubernetes persistent volume claim (persistent on `/home/coder`)\n\nThis means, when the workspace restarts, any tools or files outside of the home directory are not persisted. To pre-bake tools into the workspace (e.g. `python3`), modify the container image. Alternatively, individual developers can [personalize](https://coder.com/docs/dotfiles) their workspaces with dotfiles.\n\n\u003e **Note**\n\u003e This template is designed to be a starting point! Edit the Terraform to extend the template to support your use case.\n" + }, + { + "id": "nomad-docker", + "url": "", + "name": "Nomad", + "description": "Provision Nomad Jobs as Coder workspaces", + "icon": "/icon/nomad.svg", + "tags": [ + "nomad", + "container" + ], + "markdown": "\n# Remote Development on Nomad\n\nProvision Nomad Jobs as [Coder workspaces](https://coder.com/docs/workspaces) with this example template. This example shows how to use Nomad service tasks to be used as a development environment using docker and host csi volumes.\n\n\u003c!-- TODO: Add screenshot --\u003e\n\n\u003e **Note**\n\u003e This template is designed to be a starting point! Edit the Terraform to extend the template to support your use case.\n\n## Prerequisites\n\n- [Nomad](https://www.nomadproject.io/downloads)\n- [Docker](https://docs.docker.com/get-docker/)\n\n## Setup\n\n### 1. Start the CSI Host Volume Plugin\n\nThe CSI Host Volume plugin is used to mount host volumes into Nomad tasks. This is useful for development environments where you want to mount persistent volumes into your container workspace.\n\n1. Login to the Nomad server using SSH.\n\n2. Append the following stanza to your Nomad server configuration file and restart the nomad service.\n\n ```hcl\n plugin \"docker\" {\n config {\n allow_privileged = true\n }\n }\n ```\n\n ```shell\n sudo systemctl restart nomad\n ```\n\n3. Create a file `hostpath.nomad` with following content:\n\n ```hcl\n job \"hostpath-csi-plugin\" {\n datacenters = [\"dc1\"]\n type = \"system\"\n\n group \"csi\" {\n task \"plugin\" {\n driver = \"docker\"\n\n config {\n image = \"registry.k8s.io/sig-storage/hostpathplugin:v1.10.0\"\n\n args = [\n \"--drivername=csi-hostpath\",\n \"--v=5\",\n \"--endpoint=${CSI_ENDPOINT}\",\n \"--nodeid=node-${NOMAD_ALLOC_INDEX}\",\n ]\n\n privileged = true\n }\n\n csi_plugin {\n id = \"hostpath\"\n type = \"monolith\"\n mount_dir = \"/csi\"\n }\n\n resources {\n cpu = 256\n memory = 128\n }\n }\n }\n }\n ```\n\n4. Run the job:\n\n ```shell\n nomad job run hostpath.nomad\n ```\n\n### 2. Setup the Nomad Template\n\n1. Create the template by running the following command:\n\n ```shell\n coder template init nomad-docker\n cd nomad-docker\n coder template push\n ```\n\n2. Set up Nomad server address and optional authentication:\n\n3. Create a new workspace and start developing.\n" + }, + { + "id": "scratch", + "url": "", + "name": "Scratch", + "description": "A minimal starter template for Coder", + "icon": "/emojis/1f4e6.png", + "tags": [], + "markdown": "\n# A minimal Scaffolding for a Coder Template\n\nUse this starter template as a basis to create your own unique template from scratch.\n" + } ] diff --git a/examples/monitoring/dashboards/grafana/dashboard.json b/examples/monitoring/dashboards/grafana/dashboard.json index 60fc2f108d..d4b0ec919f 100644 --- a/examples/monitoring/dashboards/grafana/dashboard.json +++ b/examples/monitoring/dashboards/grafana/dashboard.json @@ -1,1005 +1,1005 @@ { - "__inputs": [ - { - "name": "DS_PROMETHEUS", - "label": "Prometheus", - "description": "", - "type": "datasource", - "pluginId": "prometheus", - "pluginName": "Prometheus" - }, - { - "name": "VAR_FILTER_KEY", - "type": "constant", - "label": "Filter key", - "value": "app", - "description": "" - }, - { - "name": "VAR_FILTER_VALUE", - "type": "constant", - "label": "Filter value", - "value": "coder", - "description": "" - } - ], - "__elements": {}, - "__requires": [ - { - "type": "grafana", - "id": "grafana", - "name": "Grafana", - "version": "9.5.3" - }, - { - "type": "datasource", - "id": "prometheus", - "name": "Prometheus", - "version": "1.0.0" - }, - { - "type": "panel", - "id": "stat", - "name": "Stat", - "version": "" - }, - { - "type": "panel", - "id": "timeseries", - "name": "Time series", - "version": "" - } - ], - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": { - "type": "grafana", - "uid": "-- Grafana --" - }, - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "type": "dashboard" - } - ] - }, - "editable": true, - "fiscalYearStartMonth": 0, - "graphTooltip": 0, - "id": null, - "links": [], - "liveNow": false, - "panels": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byRegexp", - "options": "/.*/" - }, - "properties": [ - { - "id": "displayName", - "value": "CPU seconds" - }, - { - "id": "unit", - "value": "s" - } - ] - } - ] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 0 - }, - "id": 1, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "rate(process_cpu_seconds_total{$filter_key=\"$filter_value\"}[$__rate_interval])", - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "CPU Usage", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 4, - "x": 12, - "y": 0 - }, - "id": 2, - "options": { - "colorMode": "value", - "graphMode": "area", - "justifyMode": "auto", - "orientation": "auto", - "reduceOptions": { - "calcs": ["lastNotNull"], - "fields": "", - "values": false - }, - "textMode": "auto" - }, - "pluginVersion": "9.5.3", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "coderd_api_active_users_duration_hour{$filter_key=\"$filter_value\"}", - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "Active Users", - "type": "stat" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 4, - "x": 16, - "y": 0 - }, - "id": 5, - "options": { - "colorMode": "value", - "graphMode": "area", - "justifyMode": "auto", - "orientation": "auto", - "reduceOptions": { - "calcs": ["lastNotNull"], - "fields": "", - "values": false - }, - "textMode": "auto" - }, - "pluginVersion": "9.5.3", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "sum(coderd_agents_up{$filter_key=\"$filter_value\"})", - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "Running agents", - "type": "stat" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "ms" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 4, - "x": 20, - "y": 0 - }, - "id": 6, - "options": { - "colorMode": "value", - "graphMode": "area", - "justifyMode": "auto", - "orientation": "auto", - "reduceOptions": { - "calcs": ["lastNotNull"], - "fields": "", - "values": false - }, - "textMode": "auto" - }, - "pluginVersion": "9.5.3", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "avg(coderd_agents_connection_latencies_seconds{$filter_key=\"$filter_value\"})", - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "Avg connection latency", - "type": "stat" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byRegexp", - "options": "/coderd_provisionerd_num_daemons/" - }, - "properties": [ - { - "id": "displayName", - "value": "Running provisioners" - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "/coderd_provisionerd_jobs_current/" - }, - "properties": [ - { - "id": "displayName", - "value": "Running jobs" - } - ] - } - ] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 8 - }, - "id": 3, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "coderd_provisionerd_jobs_current{$filter_key=\"$filter_value\"}", - "legendFormat": "__auto", - "range": true, - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "coderd_provisionerd_num_daemons{$filter_key=\"$filter_value\"}", - "hide": false, - "legendFormat": "__auto", - "range": true, - "refId": "B" - } - ], - "title": "Concurrent jobs", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "s" - }, - "overrides": [ - { - "matcher": { - "id": "byRegexp", - "options": "/.*coderd_db_query_latencies_seconds_count.*/" - }, - "properties": [ - { - "id": "unit", - "value": "none" - }, - { - "id": "displayName", - "value": "Queries/s" - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "/.*coderd_db_query_latencies_seconds_bucket.*/" - }, - "properties": [ - { - "id": "displayName", - "value": "P95 query latency" - } - ] - } - ] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 8 - }, - "id": 7, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "pluginVersion": "9.5.3", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "histogram_quantile(0.95, sum by(le) (rate(coderd_db_query_latencies_seconds_bucket{$filter_key=\"$filter_value\"}[$__rate_interval])))", - "hide": false, - "legendFormat": "__auto", - "range": true, - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "sum(rate(coderd_db_query_latencies_seconds_count{$filter_key=\"$filter_value\"}[$__rate_interval]))", - "hide": false, - "legendFormat": "__auto", - "range": true, - "refId": "B" - } - ], - "title": "Query latency and rate", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byRegexp", - "options": "/go_memstats_alloc_bytes/" - }, - "properties": [ - { - "id": "custom.axisPlacement", - "value": "left" - }, - { - "id": "unit", - "value": "bytes" - }, - { - "id": "displayName", - "value": "Allocated bytes" - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "/go_goroutines/" - }, - "properties": [ - { - "id": "displayName", - "value": "Goroutines" - } - ] - } - ] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 16 - }, - "id": 4, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "go_memstats_alloc_bytes{$filter_key=\"$filter_value\"}", - "legendFormat": "__auto", - "range": true, - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "exemplar": false, - "expr": "go_goroutines{$filter_key=\"$filter_value\"}", - "hide": false, - "legendFormat": "__auto", - "range": true, - "refId": "B" - } - ], - "title": "Heap and Goroutines", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byRegexp", - "options": "/coderd_api_requests_processed_total{code=\"500\"}/" - }, - "properties": [ - { - "id": "displayName", - "value": "Error rate" - }, - { - "id": "unit", - "value": "reqps" - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "/coderd_api_requests_processed_total/" - }, - "properties": [ - { - "id": "displayName", - "value": "Request rate" - }, - { - "id": "unit", - "value": "reqps" - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": "/coderd_api_request_latencies_seconds_bucket/" - }, - "properties": [ - { - "id": "unit", - "value": "s" - }, - { - "id": "displayName", - "value": "P95 request latency" - } - ] - } - ] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 16 - }, - "id": 8, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "sum(rate(coderd_api_requests_processed_total{$filter_key=\"$filter_value\"}[$__rate_interval]))", - "interval": "", - "legendFormat": "__auto", - "range": true, - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "sum(rate(coderd_api_requests_processed_total{code=\"500\"}[$__rate_interval]))", - "hide": false, - "legendFormat": "__auto", - "range": true, - "refId": "B" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "histogram_quantile(0.95, sum by(le) (rate(coderd_api_request_latencies_seconds_bucket[$__rate_interval])))", - "hide": false, - "legendFormat": "__auto", - "range": true, - "refId": "C" - } - ], - "title": "API Requests and Error Rate", - "type": "timeseries" - } - ], - "refresh": "10s", - "schemaVersion": 38, - "style": "dark", - "tags": [], - "templating": { - "list": [ - { - "description": "The key to use for filtering metrics", - "hide": 2, - "label": "Filter key", - "name": "filter_key", - "query": "${VAR_FILTER_KEY}", - "skipUrlSync": false, - "type": "constant", - "current": { - "value": "${VAR_FILTER_KEY}", - "text": "${VAR_FILTER_KEY}", - "selected": false - }, - "options": [ - { - "value": "${VAR_FILTER_KEY}", - "text": "${VAR_FILTER_KEY}", - "selected": false - } - ] - }, - { - "description": "The value to use for filtering metrics", - "hide": 2, - "label": "Filter value", - "name": "filter_value", - "query": "${VAR_FILTER_VALUE}", - "skipUrlSync": false, - "type": "constant", - "current": { - "value": "${VAR_FILTER_VALUE}", - "text": "${VAR_FILTER_VALUE}", - "selected": false - }, - "options": [ - { - "value": "${VAR_FILTER_VALUE}", - "text": "${VAR_FILTER_VALUE}", - "selected": false - } - ] - } - ] - }, - "time": { - "from": "now-30m", - "to": "now" - }, - "timepicker": {}, - "timezone": "", - "title": "Coder Dashboard", - "uid": "cb63c6ac-e392-42a9-a966-ee642b9c997c", - "version": 10, - "weekStart": "" + "__inputs": [ + { + "name": "DS_PROMETHEUS", + "label": "Prometheus", + "description": "", + "type": "datasource", + "pluginId": "prometheus", + "pluginName": "Prometheus" + }, + { + "name": "VAR_FILTER_KEY", + "type": "constant", + "label": "Filter key", + "value": "app", + "description": "" + }, + { + "name": "VAR_FILTER_VALUE", + "type": "constant", + "label": "Filter value", + "value": "coder", + "description": "" + } + ], + "__elements": {}, + "__requires": [ + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "9.5.3" + }, + { + "type": "datasource", + "id": "prometheus", + "name": "Prometheus", + "version": "1.0.0" + }, + { + "type": "panel", + "id": "stat", + "name": "Stat", + "version": "" + }, + { + "type": "panel", + "id": "timeseries", + "name": "Time series", + "version": "" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": null, + "links": [], + "liveNow": false, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/.*/" + }, + "properties": [ + { + "id": "displayName", + "value": "CPU seconds" + }, + { + "id": "unit", + "value": "s" + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 1, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "rate(process_cpu_seconds_total{$filter_key=\"$filter_value\"}[$__rate_interval])", + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "CPU Usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 4, + "x": 12, + "y": 0 + }, + "id": 2, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": ["lastNotNull"], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "9.5.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "coderd_api_active_users_duration_hour{$filter_key=\"$filter_value\"}", + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Active Users", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 4, + "x": 16, + "y": 0 + }, + "id": 5, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": ["lastNotNull"], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "9.5.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "sum(coderd_agents_up{$filter_key=\"$filter_value\"})", + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Running agents", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 4, + "x": 20, + "y": 0 + }, + "id": 6, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": ["lastNotNull"], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "9.5.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "avg(coderd_agents_connection_latencies_seconds{$filter_key=\"$filter_value\"})", + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Avg connection latency", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/coderd_provisionerd_num_daemons/" + }, + "properties": [ + { + "id": "displayName", + "value": "Running provisioners" + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/coderd_provisionerd_jobs_current/" + }, + "properties": [ + { + "id": "displayName", + "value": "Running jobs" + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 8 + }, + "id": 3, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "coderd_provisionerd_jobs_current{$filter_key=\"$filter_value\"}", + "legendFormat": "__auto", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "coderd_provisionerd_num_daemons{$filter_key=\"$filter_value\"}", + "hide": false, + "legendFormat": "__auto", + "range": true, + "refId": "B" + } + ], + "title": "Concurrent jobs", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/.*coderd_db_query_latencies_seconds_count.*/" + }, + "properties": [ + { + "id": "unit", + "value": "none" + }, + { + "id": "displayName", + "value": "Queries/s" + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/.*coderd_db_query_latencies_seconds_bucket.*/" + }, + "properties": [ + { + "id": "displayName", + "value": "P95 query latency" + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 8 + }, + "id": 7, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "9.5.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "histogram_quantile(0.95, sum by(le) (rate(coderd_db_query_latencies_seconds_bucket{$filter_key=\"$filter_value\"}[$__rate_interval])))", + "hide": false, + "legendFormat": "__auto", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "sum(rate(coderd_db_query_latencies_seconds_count{$filter_key=\"$filter_value\"}[$__rate_interval]))", + "hide": false, + "legendFormat": "__auto", + "range": true, + "refId": "B" + } + ], + "title": "Query latency and rate", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/go_memstats_alloc_bytes/" + }, + "properties": [ + { + "id": "custom.axisPlacement", + "value": "left" + }, + { + "id": "unit", + "value": "bytes" + }, + { + "id": "displayName", + "value": "Allocated bytes" + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/go_goroutines/" + }, + "properties": [ + { + "id": "displayName", + "value": "Goroutines" + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 16 + }, + "id": 4, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "go_memstats_alloc_bytes{$filter_key=\"$filter_value\"}", + "legendFormat": "__auto", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "exemplar": false, + "expr": "go_goroutines{$filter_key=\"$filter_value\"}", + "hide": false, + "legendFormat": "__auto", + "range": true, + "refId": "B" + } + ], + "title": "Heap and Goroutines", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/coderd_api_requests_processed_total{code=\"500\"}/" + }, + "properties": [ + { + "id": "displayName", + "value": "Error rate" + }, + { + "id": "unit", + "value": "reqps" + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/coderd_api_requests_processed_total/" + }, + "properties": [ + { + "id": "displayName", + "value": "Request rate" + }, + { + "id": "unit", + "value": "reqps" + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/coderd_api_request_latencies_seconds_bucket/" + }, + "properties": [ + { + "id": "unit", + "value": "s" + }, + { + "id": "displayName", + "value": "P95 request latency" + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 16 + }, + "id": 8, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "sum(rate(coderd_api_requests_processed_total{$filter_key=\"$filter_value\"}[$__rate_interval]))", + "interval": "", + "legendFormat": "__auto", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "sum(rate(coderd_api_requests_processed_total{code=\"500\"}[$__rate_interval]))", + "hide": false, + "legendFormat": "__auto", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "histogram_quantile(0.95, sum by(le) (rate(coderd_api_request_latencies_seconds_bucket[$__rate_interval])))", + "hide": false, + "legendFormat": "__auto", + "range": true, + "refId": "C" + } + ], + "title": "API Requests and Error Rate", + "type": "timeseries" + } + ], + "refresh": "10s", + "schemaVersion": 38, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "description": "The key to use for filtering metrics", + "hide": 2, + "label": "Filter key", + "name": "filter_key", + "query": "${VAR_FILTER_KEY}", + "skipUrlSync": false, + "type": "constant", + "current": { + "value": "${VAR_FILTER_KEY}", + "text": "${VAR_FILTER_KEY}", + "selected": false + }, + "options": [ + { + "value": "${VAR_FILTER_KEY}", + "text": "${VAR_FILTER_KEY}", + "selected": false + } + ] + }, + { + "description": "The value to use for filtering metrics", + "hide": 2, + "label": "Filter value", + "name": "filter_value", + "query": "${VAR_FILTER_VALUE}", + "skipUrlSync": false, + "type": "constant", + "current": { + "value": "${VAR_FILTER_VALUE}", + "text": "${VAR_FILTER_VALUE}", + "selected": false + }, + "options": [ + { + "value": "${VAR_FILTER_VALUE}", + "text": "${VAR_FILTER_VALUE}", + "selected": false + } + ] + } + ] + }, + "time": { + "from": "now-30m", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Coder Dashboard", + "uid": "cb63c6ac-e392-42a9-a966-ee642b9c997c", + "version": 10, + "weekStart": "" } diff --git a/examples/templates/aws-devcontainer/README.md b/examples/templates/aws-devcontainer/README.md index a72465b20b..cea65bb8b9 100644 --- a/examples/templates/aws-devcontainer/README.md +++ b/examples/templates/aws-devcontainer/README.md @@ -31,50 +31,50 @@ instances provisioned by Coder: ```json { - "Version": "2012-10-17", - "Statement": [ - { - "Sid": "VisualEditor0", - "Effect": "Allow", - "Action": [ - "ec2:GetDefaultCreditSpecification", - "ec2:DescribeIamInstanceProfileAssociations", - "ec2:DescribeTags", - "ec2:DescribeInstances", - "ec2:DescribeInstanceTypes", - "ec2:CreateTags", - "ec2:RunInstances", - "ec2:DescribeInstanceCreditSpecifications", - "ec2:DescribeImages", - "ec2:ModifyDefaultCreditSpecification", - "ec2:DescribeVolumes" - ], - "Resource": "*" - }, - { - "Sid": "CoderResources", - "Effect": "Allow", - "Action": [ - "ec2:DescribeInstanceAttribute", - "ec2:UnmonitorInstances", - "ec2:TerminateInstances", - "ec2:StartInstances", - "ec2:StopInstances", - "ec2:DeleteTags", - "ec2:MonitorInstances", - "ec2:CreateTags", - "ec2:RunInstances", - "ec2:ModifyInstanceAttribute", - "ec2:ModifyInstanceCreditSpecification" - ], - "Resource": "arn:aws:ec2:*:*:instance/*", - "Condition": { - "StringEquals": { - "aws:ResourceTag/Coder_Provisioned": "true" - } - } - } - ] + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "VisualEditor0", + "Effect": "Allow", + "Action": [ + "ec2:GetDefaultCreditSpecification", + "ec2:DescribeIamInstanceProfileAssociations", + "ec2:DescribeTags", + "ec2:DescribeInstances", + "ec2:DescribeInstanceTypes", + "ec2:CreateTags", + "ec2:RunInstances", + "ec2:DescribeInstanceCreditSpecifications", + "ec2:DescribeImages", + "ec2:ModifyDefaultCreditSpecification", + "ec2:DescribeVolumes" + ], + "Resource": "*" + }, + { + "Sid": "CoderResources", + "Effect": "Allow", + "Action": [ + "ec2:DescribeInstanceAttribute", + "ec2:UnmonitorInstances", + "ec2:TerminateInstances", + "ec2:StartInstances", + "ec2:StopInstances", + "ec2:DeleteTags", + "ec2:MonitorInstances", + "ec2:CreateTags", + "ec2:RunInstances", + "ec2:ModifyInstanceAttribute", + "ec2:ModifyInstanceCreditSpecification" + ], + "Resource": "arn:aws:ec2:*:*:instance/*", + "Condition": { + "StringEquals": { + "aws:ResourceTag/Coder_Provisioned": "true" + } + } + } + ] } ``` diff --git a/examples/templates/aws-linux/README.md b/examples/templates/aws-linux/README.md index fc629ee4de..e7ba990586 100644 --- a/examples/templates/aws-linux/README.md +++ b/examples/templates/aws-linux/README.md @@ -30,50 +30,50 @@ instances provisioned by Coder: ```json { - "Version": "2012-10-17", - "Statement": [ - { - "Sid": "VisualEditor0", - "Effect": "Allow", - "Action": [ - "ec2:GetDefaultCreditSpecification", - "ec2:DescribeIamInstanceProfileAssociations", - "ec2:DescribeTags", - "ec2:DescribeInstances", - "ec2:DescribeInstanceTypes", - "ec2:CreateTags", - "ec2:RunInstances", - "ec2:DescribeInstanceCreditSpecifications", - "ec2:DescribeImages", - "ec2:ModifyDefaultCreditSpecification", - "ec2:DescribeVolumes" - ], - "Resource": "*" - }, - { - "Sid": "CoderResources", - "Effect": "Allow", - "Action": [ - "ec2:DescribeInstanceAttribute", - "ec2:UnmonitorInstances", - "ec2:TerminateInstances", - "ec2:StartInstances", - "ec2:StopInstances", - "ec2:DeleteTags", - "ec2:MonitorInstances", - "ec2:CreateTags", - "ec2:RunInstances", - "ec2:ModifyInstanceAttribute", - "ec2:ModifyInstanceCreditSpecification" - ], - "Resource": "arn:aws:ec2:*:*:instance/*", - "Condition": { - "StringEquals": { - "aws:ResourceTag/Coder_Provisioned": "true" - } - } - } - ] + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "VisualEditor0", + "Effect": "Allow", + "Action": [ + "ec2:GetDefaultCreditSpecification", + "ec2:DescribeIamInstanceProfileAssociations", + "ec2:DescribeTags", + "ec2:DescribeInstances", + "ec2:DescribeInstanceTypes", + "ec2:CreateTags", + "ec2:RunInstances", + "ec2:DescribeInstanceCreditSpecifications", + "ec2:DescribeImages", + "ec2:ModifyDefaultCreditSpecification", + "ec2:DescribeVolumes" + ], + "Resource": "*" + }, + { + "Sid": "CoderResources", + "Effect": "Allow", + "Action": [ + "ec2:DescribeInstanceAttribute", + "ec2:UnmonitorInstances", + "ec2:TerminateInstances", + "ec2:StartInstances", + "ec2:StopInstances", + "ec2:DeleteTags", + "ec2:MonitorInstances", + "ec2:CreateTags", + "ec2:RunInstances", + "ec2:ModifyInstanceAttribute", + "ec2:ModifyInstanceCreditSpecification" + ], + "Resource": "arn:aws:ec2:*:*:instance/*", + "Condition": { + "StringEquals": { + "aws:ResourceTag/Coder_Provisioned": "true" + } + } + } + ] } ``` diff --git a/examples/templates/aws-windows/README.md b/examples/templates/aws-windows/README.md index f577d88dee..5f4f670f27 100644 --- a/examples/templates/aws-windows/README.md +++ b/examples/templates/aws-windows/README.md @@ -30,50 +30,50 @@ instances provisioned by Coder: ```json { - "Version": "2012-10-17", - "Statement": [ - { - "Sid": "VisualEditor0", - "Effect": "Allow", - "Action": [ - "ec2:GetDefaultCreditSpecification", - "ec2:DescribeIamInstanceProfileAssociations", - "ec2:DescribeTags", - "ec2:DescribeInstances", - "ec2:DescribeInstanceTypes", - "ec2:CreateTags", - "ec2:RunInstances", - "ec2:DescribeInstanceCreditSpecifications", - "ec2:DescribeImages", - "ec2:ModifyDefaultCreditSpecification", - "ec2:DescribeVolumes" - ], - "Resource": "*" - }, - { - "Sid": "CoderResources", - "Effect": "Allow", - "Action": [ - "ec2:DescribeInstanceAttribute", - "ec2:UnmonitorInstances", - "ec2:TerminateInstances", - "ec2:StartInstances", - "ec2:StopInstances", - "ec2:DeleteTags", - "ec2:MonitorInstances", - "ec2:CreateTags", - "ec2:RunInstances", - "ec2:ModifyInstanceAttribute", - "ec2:ModifyInstanceCreditSpecification" - ], - "Resource": "arn:aws:ec2:*:*:instance/*", - "Condition": { - "StringEquals": { - "aws:ResourceTag/Coder_Provisioned": "true" - } - } - } - ] + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "VisualEditor0", + "Effect": "Allow", + "Action": [ + "ec2:GetDefaultCreditSpecification", + "ec2:DescribeIamInstanceProfileAssociations", + "ec2:DescribeTags", + "ec2:DescribeInstances", + "ec2:DescribeInstanceTypes", + "ec2:CreateTags", + "ec2:RunInstances", + "ec2:DescribeInstanceCreditSpecifications", + "ec2:DescribeImages", + "ec2:ModifyDefaultCreditSpecification", + "ec2:DescribeVolumes" + ], + "Resource": "*" + }, + { + "Sid": "CoderResources", + "Effect": "Allow", + "Action": [ + "ec2:DescribeInstanceAttribute", + "ec2:UnmonitorInstances", + "ec2:TerminateInstances", + "ec2:StartInstances", + "ec2:StopInstances", + "ec2:DeleteTags", + "ec2:MonitorInstances", + "ec2:CreateTags", + "ec2:RunInstances", + "ec2:ModifyInstanceAttribute", + "ec2:ModifyInstanceCreditSpecification" + ], + "Resource": "arn:aws:ec2:*:*:instance/*", + "Condition": { + "StringEquals": { + "aws:ResourceTag/Coder_Provisioned": "true" + } + } + } + ] } ``` diff --git a/offlinedocs/.eslintrc.json b/offlinedocs/.eslintrc.json index bffb357a71..72cc705c1d 100644 --- a/offlinedocs/.eslintrc.json +++ b/offlinedocs/.eslintrc.json @@ -1,3 +1,3 @@ { - "extends": "next/core-web-vitals" + "extends": "next/core-web-vitals" } diff --git a/offlinedocs/next.config.js b/offlinedocs/next.config.js index 9768feee70..0d332a9b77 100644 --- a/offlinedocs/next.config.js +++ b/offlinedocs/next.config.js @@ -1,8 +1,8 @@ /** @type {import('next').NextConfig} */ const nextConfig = { - output: "export", - reactStrictMode: true, - trailingSlash: true, + output: "export", + reactStrictMode: true, + trailingSlash: true, }; module.exports = nextConfig; diff --git a/offlinedocs/package.json b/offlinedocs/package.json index 1f1f6b8f06..85a51bffd9 100644 --- a/offlinedocs/package.json +++ b/offlinedocs/package.json @@ -1,45 +1,45 @@ { - "name": "coder-docs-generator", - "private": true, - "scripts": { - "dev": "pnpm copy-images && next dev", - "build": "next build", - "start": "next start", - "export": "pnpm copy-images && next build", - "copy-images": "sh ./scripts/copyImages.sh", - "lint": "pnpm run lint:types", - "lint:types": "tsc --noEmit", - "format": "prettier --cache --write './**/*.{css,html,js,json,jsx,md,ts,tsx,yaml,yml}'", - "format:check": "prettier --cache --check './**/*.{css,html,js,json,jsx,md,ts,tsx,yaml,yml}'" - }, - "dependencies": { - "@chakra-ui/react": "2.8.2", - "@emotion/react": "11.11.4", - "@emotion/styled": "11.11.5", - "archiver": "6.0.2", - "framer-motion": "^10.17.6", - "front-matter": "4.0.2", - "lodash": "4.17.21", - "next": "14.2.4", - "react": "18.3.1", - "react-dom": "18.3.1", - "react-icons": "4.12.0", - "react-markdown": "9.0.1", - "rehype-raw": "7.0.0", - "remark-gfm": "4.0.0" - }, - "devDependencies": { - "@types/lodash": "4.14.196", - "@types/node": "18.19.0", - "@types/react": "18.3.3", - "@types/react-dom": "18.3.0", - "eslint": "8.56.0", - "eslint-config-next": "14.0.1", - "prettier": "3.3.3", - "typescript": "5.3.2" - }, - "engines": { - "npm": ">=9.0.0 <10.0.0", - "node": ">=18.0.0 <21.0.0" - } + "name": "coder-docs-generator", + "private": true, + "scripts": { + "dev": "pnpm copy-images && next dev", + "build": "next build", + "start": "next start", + "export": "pnpm copy-images && next build", + "copy-images": "sh ./scripts/copyImages.sh", + "lint": "pnpm run lint:types", + "lint:types": "tsc --noEmit", + "format": "prettier --cache --write './**/*.{css,html,js,json,jsx,md,ts,tsx,yaml,yml}'", + "format:check": "prettier --cache --check './**/*.{css,html,js,json,jsx,md,ts,tsx,yaml,yml}'" + }, + "dependencies": { + "@chakra-ui/react": "2.8.2", + "@emotion/react": "11.11.4", + "@emotion/styled": "11.11.5", + "archiver": "6.0.2", + "framer-motion": "^10.17.6", + "front-matter": "4.0.2", + "lodash": "4.17.21", + "next": "14.2.4", + "react": "18.3.1", + "react-dom": "18.3.1", + "react-icons": "4.12.0", + "react-markdown": "9.0.1", + "rehype-raw": "7.0.0", + "remark-gfm": "4.0.0" + }, + "devDependencies": { + "@types/lodash": "4.14.196", + "@types/node": "18.19.0", + "@types/react": "18.3.3", + "@types/react-dom": "18.3.0", + "eslint": "8.56.0", + "eslint-config-next": "14.0.1", + "prettier": "3.3.3", + "typescript": "5.3.2" + }, + "engines": { + "npm": ">=9.0.0 <10.0.0", + "node": ">=18.0.0 <21.0.0" + } } diff --git a/offlinedocs/pages/[[...slug]].tsx b/offlinedocs/pages/[[...slug]].tsx index bffa934216..517ed25930 100644 --- a/offlinedocs/pages/[[...slug]].tsx +++ b/offlinedocs/pages/[[...slug]].tsx @@ -1,29 +1,29 @@ import { - Box, - Button, - Code, - Drawer, - DrawerBody, - DrawerCloseButton, - DrawerContent, - DrawerOverlay, - Flex, - Grid, - GridProps, - Heading, - Icon, - Img, - Link, - OrderedList, - Table, - TableContainer, - Td, - Text, - Th, - Thead, - Tr, - UnorderedList, - useDisclosure, + Box, + Button, + Code, + Drawer, + DrawerBody, + DrawerCloseButton, + DrawerContent, + DrawerOverlay, + Flex, + Grid, + GridProps, + Heading, + Icon, + Img, + Link, + OrderedList, + Table, + TableContainer, + Td, + Text, + Th, + Thead, + Tr, + UnorderedList, + useDisclosure, } from "@chakra-ui/react"; import fm from "front-matter"; import { readFileSync } from "fs"; @@ -42,19 +42,19 @@ import remarkGfm from "remark-gfm"; type FilePath = string; type UrlPath = string; type Route = { - path: FilePath; - title: string; - description?: string; - children?: Route[]; + path: FilePath; + title: string; + description?: string; + children?: Route[]; }; type Manifest = { versions: string[]; routes: Route[] }; type NavItem = { title: string; path: UrlPath; children?: NavItem[] }; type Nav = NavItem[]; const readContentFile = (filePath: string) => { - const baseDir = process.cwd(); - const docsPath = path.join(baseDir, "..", "docs"); - return readFileSync(path.join(docsPath, filePath), { encoding: "utf-8" }); + const baseDir = process.cwd(); + const docsPath = path.join(baseDir, "..", "docs"); + return readFileSync(path.join(docsPath, filePath), { encoding: "utf-8" }); }; const removeTrailingSlash = (path: string) => path.replace(/\/+$/, ""); @@ -62,19 +62,19 @@ const removeTrailingSlash = (path: string) => path.replace(/\/+$/, ""); const removeMkdExtension = (path: string) => path.replace(/\.md/g, ""); const removeIndexFilename = (path: string) => { - if (path.endsWith("index")) { - path = path.replace("index", ""); - } + if (path.endsWith("index")) { + path = path.replace("index", ""); + } - return path; + return path; }; const removeREADMEName = (path: string) => { - if (path.startsWith("README")) { - path = path.replace("README", ""); - } + if (path.startsWith("README")) { + path = path.replace("README", ""); + } - return path; + return path; }; // transformLinkUri converts the links in the markdown file to @@ -87,466 +87,466 @@ const removeREADMEName = (path: string) => { // file.md -> ./subdir/file = ../subdir/file // file.md -> ../file-next-to-file = ../file-next-to-file const transformLinkUriSource = (sourceFile: string) => { - return (href = "") => { - const isExternal = href.startsWith("http") || href.startsWith("https"); - if (!isExternal) { - // Remove .md form the path - href = removeMkdExtension(href); + return (href = "") => { + const isExternal = href.startsWith("http") || href.startsWith("https"); + if (!isExternal) { + // Remove .md form the path + href = removeMkdExtension(href); - // Add the extra '..' if not an index file. - sourceFile = removeMkdExtension(sourceFile); - if (!sourceFile.endsWith("index")) { - href = "../" + href; - } + // Add the extra '..' if not an index file. + sourceFile = removeMkdExtension(sourceFile); + if (!sourceFile.endsWith("index")) { + href = "../" + href; + } - // Remove the index path - href = removeIndexFilename(href); - href = removeREADMEName(href); - } - return href; - }; + // Remove the index path + href = removeIndexFilename(href); + href = removeREADMEName(href); + } + return href; + }; }; const transformFilePathToUrlPath = (filePath: string) => { - // Remove markdown extension - let urlPath = removeMkdExtension(filePath); + // Remove markdown extension + let urlPath = removeMkdExtension(filePath); - // Remove relative path - if (urlPath.startsWith("./")) { - urlPath = urlPath.replace("./", ""); - } + // Remove relative path + if (urlPath.startsWith("./")) { + urlPath = urlPath.replace("./", ""); + } - // Remove index from the root file - urlPath = removeIndexFilename(urlPath); - urlPath = removeREADMEName(urlPath); + // Remove index from the root file + urlPath = removeIndexFilename(urlPath); + urlPath = removeREADMEName(urlPath); - // Remove trailing slash - if (urlPath.endsWith("/")) { - urlPath = removeTrailingSlash(urlPath); - } + // Remove trailing slash + if (urlPath.endsWith("/")) { + urlPath = removeTrailingSlash(urlPath); + } - return urlPath; + return urlPath; }; const mapRoutes = (manifest: Manifest): Record => { - const paths: Record = {}; + const paths: Record = {}; - const addPaths = (routes: Route[]) => { - for (const route of routes) { - paths[transformFilePathToUrlPath(route.path)] = route; + const addPaths = (routes: Route[]) => { + for (const route of routes) { + paths[transformFilePathToUrlPath(route.path)] = route; - if (route.children) { - addPaths(route.children); - } - } - }; + if (route.children) { + addPaths(route.children); + } + } + }; - addPaths(manifest.routes); + addPaths(manifest.routes); - return paths; + return paths; }; let manifest: Manifest | undefined; const getManifest = () => { - if (manifest) { - return manifest; - } + if (manifest) { + return manifest; + } - const manifestContent = readContentFile("manifest.json"); - manifest = JSON.parse(manifestContent) as Manifest; - return manifest; + const manifestContent = readContentFile("manifest.json"); + manifest = JSON.parse(manifestContent) as Manifest; + return manifest; }; let navigation: Nav | undefined; const getNavigation = (manifest: Manifest): Nav => { - if (navigation) { - return navigation; - } + if (navigation) { + return navigation; + } - const getNavItem = (route: Route, parentPath?: UrlPath): NavItem => { - const path = parentPath - ? `${parentPath}/${transformFilePathToUrlPath(route.path)}` - : transformFilePathToUrlPath(route.path); - const navItem: NavItem = { - title: route.title, - path, - }; + const getNavItem = (route: Route, parentPath?: UrlPath): NavItem => { + const path = parentPath + ? `${parentPath}/${transformFilePathToUrlPath(route.path)}` + : transformFilePathToUrlPath(route.path); + const navItem: NavItem = { + title: route.title, + path, + }; - if (route.children) { - navItem.children = []; + if (route.children) { + navItem.children = []; - for (const childRoute of route.children) { - navItem.children.push(getNavItem(childRoute)); - } - } + for (const childRoute of route.children) { + navItem.children.push(getNavItem(childRoute)); + } + } - return navItem; - }; + return navItem; + }; - navigation = []; + navigation = []; - for (const route of manifest.routes) { - navigation.push(getNavItem(route)); - } + for (const route of manifest.routes) { + navigation.push(getNavItem(route)); + } - return navigation; + return navigation; }; const removeHtmlComments = (string: string) => { - return string.replace(//g, ""); + return string.replace(//g, ""); }; export const getStaticPaths: GetStaticPaths = () => { - const manifest = getManifest(); - const routes = mapRoutes(manifest); - const paths = Object.keys(routes).map((urlPath) => ({ - params: { slug: urlPath.split("/") }, - })); + const manifest = getManifest(); + const routes = mapRoutes(manifest); + const paths = Object.keys(routes).map((urlPath) => ({ + params: { slug: urlPath.split("/") }, + })); - return { - paths, - fallback: false, - }; + return { + paths, + fallback: false, + }; }; export const getStaticProps: GetStaticProps = (context) => { - // When it is home page, the slug is undefined because there is no url path - // so we make it an empty string to work good with the mapRoutes - const { slug = [""] } = context.params as { slug: string[] }; - const manifest = getManifest(); - const routes = mapRoutes(manifest); - const urlPath = slug.join("/"); - const route = routes[urlPath]; - const { body } = fm(readContentFile(route.path)); - // Serialize MDX to support custom components - const content = removeHtmlComments(body); - const navigation = getNavigation(manifest); - const version = manifest.versions[0]; + // When it is home page, the slug is undefined because there is no url path + // so we make it an empty string to work good with the mapRoutes + const { slug = [""] } = context.params as { slug: string[] }; + const manifest = getManifest(); + const routes = mapRoutes(manifest); + const urlPath = slug.join("/"); + const route = routes[urlPath]; + const { body } = fm(readContentFile(route.path)); + // Serialize MDX to support custom components + const content = removeHtmlComments(body); + const navigation = getNavigation(manifest); + const version = manifest.versions[0]; - return { - props: { - content, - navigation, - route, - version, - }, - }; + return { + props: { + content, + navigation, + route, + version, + }, + }; }; const SidebarNavItem: React.FC<{ item: NavItem; nav: Nav }> = ({ - item, - nav, + item, + nav, }) => { - const router = useRouter(); - let isActive = router.asPath.startsWith(`/${item.path}`); + const router = useRouter(); + let isActive = router.asPath.startsWith(`/${item.path}`); - // Special case to handle the home path - if (item.path === "") { - isActive = router.asPath === "/"; + // Special case to handle the home path + if (item.path === "") { + isActive = router.asPath === "/"; - // Special case to handle the home path children - const homeNav = nav.find((navItem) => navItem.path === "") as NavItem; - const homeNavPaths = - homeNav.children?.map((item) => `/${item.path}/`) ?? []; - if (homeNavPaths.includes(router.asPath)) { - isActive = true; - } - } + // Special case to handle the home path children + const homeNav = nav.find((navItem) => navItem.path === "") as NavItem; + const homeNavPaths = + homeNav.children?.map((item) => `/${item.path}/`) ?? []; + if (homeNavPaths.includes(router.asPath)) { + isActive = true; + } + } - return ( - - - - {item.title} - - + return ( + + + + {item.title} + + - {isActive && item.children && ( - - {item.children.map((subItem) => ( - - ))} - - )} - - ); + {isActive && item.children && ( + + {item.children.map((subItem) => ( + + ))} + + )} + + ); }; const SidebarNav: React.FC<{ nav: Nav; version: string } & GridProps> = ({ - nav, - version, - ...gridProps + nav, + version, + ...gridProps }) => { - return ( - - - Coder logo - + return ( + + + Coder logo + - {nav.map((navItem) => ( - - ))} - - ); + {nav.map((navItem) => ( + + ))} + + ); }; const MobileNavbar: React.FC<{ nav: Nav; version: string }> = ({ - nav, - version, + nav, + version, }) => { - const { isOpen, onOpen, onClose } = useDisclosure(); + const { isOpen, onOpen, onClose } = useDisclosure(); - return ( - <> - - Coder logo + return ( + <> + + Coder logo - - + + - - - - - - - - - - - ); + + + + + + + + + + + ); }; const slugifyTitle = (titleSource: ReactNode) => { - if (Array.isArray(titleSource) && typeof titleSource[0] === "string") { - return _.kebabCase(titleSource[0].toLowerCase()); - } + if (Array.isArray(titleSource) && typeof titleSource[0] === "string") { + return _.kebabCase(titleSource[0].toLowerCase()); + } - return undefined; + return undefined; }; const getImageUrl = (src: string | undefined) => { - if (src === undefined) { - return ""; - } - const assetPath = src.split("images/")[1]; - return `/images/${assetPath}`; + if (src === undefined) { + return ""; + } + const assetPath = src.split("images/")[1]; + return `/images/${assetPath}`; }; const DocsPage: NextPage<{ - content: string; - navigation: Nav; - route: Route; - version: string; + content: string; + navigation: Nav; + route: Route; + version: string; }> = ({ content, navigation, route, version }) => { - return ( - <> - - {route.title} - - - - - - + return ( + <> + + {route.title} + + + + + + - - - + + + - - - - {/* Some docs don't have the title */} - - {route.title} - + + + + {/* Some docs don't have the title */} + + {route.title} + - ( - - {children} - - ), + ( + + {children} + + ), - h2: ({ children }) => ( - - {children} - - ), - h3: ({ children }) => ( - - {children} - - ), - img: ({ src }) => ( - - ), - p: ({ children }) => ( - - {children} - - ), - ul: ({ children }) => ( - - {children} - - ), - ol: ({ children }) => ( - - {children} - - ), - a: ({ children, href = "" }) => { - const isExternal = - href.startsWith("http") || href.startsWith("https"); + h2: ({ children }) => ( + + {children} + + ), + h3: ({ children }) => ( + + {children} + + ), + img: ({ src }) => ( + + ), + p: ({ children }) => ( + + {children} + + ), + ul: ({ children }) => ( + + {children} + + ), + ol: ({ children }) => ( + + {children} + + ), + a: ({ children, href = "" }) => { + const isExternal = + href.startsWith("http") || href.startsWith("https"); - return ( - - {children} - - ); - }, - code: ({ node, ...props }) => ( - - ), - pre: ({ children }) => ( - code": { w: "full", p: 4, rounded: "md" } }} - mb={2} - > - {children} - - ), - table: ({ children }) => ( - - {children}
-
- ), - thead: ({ children }) => {children}, - th: ({ children }) => {children}, - td: ({ children }) => {children}, - tr: ({ children }) => {children}, - }} - > - {content} -
-
-
-
-
- - ); + return ( + + {children} + + ); + }, + code: ({ node, ...props }) => ( + + ), + pre: ({ children }) => ( + code": { w: "full", p: 4, rounded: "md" } }} + mb={2} + > + {children} + + ), + table: ({ children }) => ( + + {children}
+
+ ), + thead: ({ children }) => {children}, + th: ({ children }) => {children}, + td: ({ children }) => {children}, + tr: ({ children }) => {children}, + }} + > + {content} + +
+
+
+
+ + ); }; export default DocsPage; diff --git a/offlinedocs/pages/_app.tsx b/offlinedocs/pages/_app.tsx index 31bd99af73..6962e10d84 100644 --- a/offlinedocs/pages/_app.tsx +++ b/offlinedocs/pages/_app.tsx @@ -3,27 +3,27 @@ import type { AppProps } from "next/app"; import Head from "next/head"; const theme = extendTheme({ - styles: { - global: { - body: { - bg: "gray.50", - }, - }, - }, + styles: { + global: { + body: { + bg: "gray.50", + }, + }, + }, }); const MyApp: React.FC = ({ Component, pageProps }) => { - return ( - <> - - - - - - - - - ); + return ( + <> + + + + + + + + + ); }; export default MyApp; diff --git a/offlinedocs/tsconfig.json b/offlinedocs/tsconfig.json index 64673056fc..bb5fdbff4b 100644 --- a/offlinedocs/tsconfig.json +++ b/offlinedocs/tsconfig.json @@ -1,20 +1,20 @@ { - "compilerOptions": { - "target": "es5", - "lib": ["dom", "dom.iterable", "esnext"], - "allowJs": true, - "skipLibCheck": true, - "strict": true, - "forceConsistentCasingInFileNames": true, - "noEmit": true, - "esModuleInterop": true, - "module": "esnext", - "moduleResolution": "node", - "resolveJsonModule": true, - "isolatedModules": true, - "jsx": "preserve", - "incremental": true - }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], - "exclude": ["node_modules", "docs"] + "compilerOptions": { + "target": "es5", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], + "exclude": ["node_modules", "docs"] } diff --git a/package.json b/package.json index 3b6733121d..c72acb8c1c 100644 --- a/package.json +++ b/package.json @@ -1,14 +1,14 @@ { - "_comment": "This version doesn't matter, it's just to allow importing from other repos.", - "name": "coder", - "version": "0.0.0", - "packageManager": "pnpm@9.7.1+sha512.faf344af2d6ca65c4c5c8c2224ea77a81a5e8859cbc4e06b1511ddce2f0151512431dd19e6aff31f2c6a8f5f2aced9bd2273e1fed7dd4de1868984059d2c4247", - "scripts": { - "format": "prettier --cache --write '**/*.{css,html,json,md,yaml,yml}'", - "format:check": "prettier --cache --check '**/*.{css,html,json,md,yaml,yml}'", - "storybook": "pnpm run -C site/ storybook" - }, - "devDependencies": { - "prettier": "3.3.3" - } + "_comment": "This version doesn't matter, it's just to allow importing from other repos.", + "name": "coder", + "version": "0.0.0", + "packageManager": "pnpm@9.7.1+sha512.faf344af2d6ca65c4c5c8c2224ea77a81a5e8859cbc4e06b1511ddce2f0151512431dd19e6aff31f2c6a8f5f2aced9bd2273e1fed7dd4de1868984059d2c4247", + "scripts": { + "format": "prettier --cache --write '**/*.{css,html,json,md,yaml,yml}'", + "format:check": "prettier --cache --check '**/*.{css,html,json,md,yaml,yml}'", + "storybook": "pnpm run -C site/ storybook" + }, + "devDependencies": { + "prettier": "3.3.3" + } } diff --git a/scaletest/scaletest_dashboard.json b/scaletest/scaletest_dashboard.json index f744805883..b6d5184c3b 100644 --- a/scaletest/scaletest_dashboard.json +++ b/scaletest/scaletest_dashboard.json @@ -1,5059 +1,5059 @@ { - "__inputs": [ - { - "name": "DS_PROMETHEUS", - "label": "Prometheus", - "description": "", - "type": "datasource", - "pluginId": "prometheus", - "pluginName": "Prometheus" - }, - { - "name": "DS_GOOGLE_CLOUD MONITORING", - "label": "Google Cloud Monitoring", - "description": "", - "type": "datasource", - "pluginId": "stackdriver", - "pluginName": "Google Cloud Monitoring" - }, - { - "name": "DS_GOOGLE_CLOUD LOGGING :: V2-LOADTEST", - "label": "Google Cloud Logging :: v2-loadtest", - "description": "", - "type": "datasource", - "pluginId": "googlecloud-logging-datasource", - "pluginName": "Google Cloud Logging" - } - ], - "__elements": {}, - "__requires": [ - { - "type": "panel", - "id": "barchart", - "name": "Bar chart", - "version": "" - }, - { - "type": "datasource", - "id": "googlecloud-logging-datasource", - "name": "Google Cloud Logging", - "version": "1.3.0" - }, - { - "type": "grafana", - "id": "grafana", - "name": "Grafana", - "version": "11.1.0" - }, - { - "type": "panel", - "id": "heatmap", - "name": "Heatmap", - "version": "" - }, - { - "type": "panel", - "id": "logs", - "name": "Logs", - "version": "" - }, - { - "type": "datasource", - "id": "prometheus", - "name": "Prometheus", - "version": "1.0.0" - }, - { - "type": "datasource", - "id": "stackdriver", - "name": "Google Cloud Monitoring", - "version": "11.1.0" - }, - { - "type": "panel", - "id": "timeseries", - "name": "Time series", - "version": "" - } - ], - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": { - "type": "grafana", - "uid": "-- Grafana --" - }, - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "target": { - "limit": 100, - "matchAny": false, - "tags": [], - "type": "dashboard" - }, - "type": "dashboard" - }, - { - "datasource": { - "type": "datasource", - "uid": "grafana" - }, - "enable": true, - "iconColor": "red", - "name": "Scaletest Error", - "target": { - "refId": "Anno", - "tags": ["scaletest", "runner", "error"], - "type": "tags" - } - }, - { - "datasource": { - "type": "datasource", - "uid": "grafana" - }, - "enable": true, - "iconColor": "green", - "name": "Scaletest Phase", - "target": { - "refId": "Anno", - "tags": ["scaletest", "runner", "phase-default"], - "type": "tags" - } - }, - { - "datasource": { - "type": "datasource", - "uid": "grafana" - }, - "enable": true, - "iconColor": "transparent", - "name": "Scaletest Phase (Wait)", - "target": { - "refId": "Anno", - "tags": ["scaletest", "runner", "phase-wait"], - "type": "tags" - } - }, - { - "datasource": { - "type": "datasource", - "uid": "grafana" - }, - "enable": true, - "iconColor": "blue", - "name": "Scaletest Status", - "target": { - "refId": "Anno", - "tags": ["scaletest", "runner", "status"], - "type": "tags" - } - }, - { - "datasource": { - "type": "datasource", - "uid": "grafana" - }, - "enable": true, - "iconColor": "dark-green", - "name": "Concurrent Scenarios", - "target": { - "refId": "Anno", - "tags": ["scaletest", "runner", "scenario"], - "type": "tags" - } - }, - { - "datasource": { - "type": "datasource", - "uid": "grafana" - }, - "enable": true, - "iconColor": "semi-dark-orange", - "name": "Greedy agent", - "target": { - "refId": "Anno", - "tags": ["scaletest", "runner", "greedy_agent"], - "type": "tags" - } - }, - { - "datasource": { - "type": "datasource", - "uid": "grafana" - }, - "enable": false, - "iconColor": "super-light-purple", - "name": "Scaletest Runner Workspace", - "target": { - "refId": "Anno", - "tags": ["scaletest", "runner", "workspace"], - "type": "tags" - } - }, - { - "datasource": { - "type": "datasource", - "uid": "grafana" - }, - "enable": false, - "iconColor": "super-light-orange", - "name": "Pprof", - "target": { - "limit": 100, - "matchAny": false, - "tags": ["scaletest", "runner", "pprof"], - "type": "tags" - } - } - ] - }, - "editable": true, - "fiscalYearStartMonth": 0, - "graphTooltip": 1, - "id": null, - "links": [], - "liveNow": false, - "panels": [ - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 15, - "panels": [], - "title": "Control Plane Resources", - "type": "row" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": 60000, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "requests" - }, - "properties": [ - { - "id": "custom.spanNulls", - "value": true - }, - { - "id": "custom.lineStyle", - "value": { - "dash": [10, 10], - "fill": "dash" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "limit" - }, - "properties": [ - { - "id": "custom.spanNulls", - "value": true - }, - { - "id": "custom.lineStyle", - "value": { - "dash": [10, 10], - "fill": "dash" - } - } - ] - } - ] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 1 - }, - "id": 9, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "sum by(pod) (rate(container_cpu_usage_seconds_total{cluster=~\"$cluster\", namespace=~\"$namespace\", container=~\"^(coder|provisionerd)$\"}[$__rate_interval])) ", - "hide": false, - "legendFormat": "{{label_name}}", - "range": true, - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "exemplar": false, - "expr": "max (kube_pod_container_resource_requests{cluster=~\"$cluster\", namespace=~\"$namespace\", resource=\"cpu\", container=~\"^(coder|provisionerd)$\"})", - "hide": false, - "instant": false, - "legendFormat": "requests", - "range": true, - "refId": "B" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "exemplar": false, - "expr": "max (kube_pod_container_resource_limits{cluster=~\"$cluster\", namespace=~\"$namespace\", resource=\"cpu\", container=~\"^(coder|provisionerd)$\"})", - "hide": false, - "instant": false, - "legendFormat": "limit", - "range": true, - "refId": "C" - } - ], - "title": "Coder CPU usage", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "axisSoftMin": 0, - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": 60000, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - } - ] - }, - "unit": "bytes" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "requests" - }, - "properties": [ - { - "id": "custom.spanNulls", - "value": true - }, - { - "id": "custom.lineStyle", - "value": { - "dash": [10, 10], - "fill": "dash" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "limit" - }, - "properties": [ - { - "id": "custom.spanNulls", - "value": true - }, - { - "id": "custom.lineStyle", - "value": { - "dash": [10, 10], - "fill": "dash" - } - } - ] - } - ] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 1 - }, - "id": 10, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "sum by(pod) (container_memory_working_set_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\", container=~\"^(coder|provisionerd)$\"})", - "hide": false, - "legendFormat": "__auto", - "range": true, - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "max (kube_pod_container_resource_requests{cluster=~\"$cluster\", namespace=~\"$namespace\", resource=\"memory\", container=~\"^(coder|provisionerd)$\"})", - "hide": false, - "legendFormat": "requests", - "range": true, - "refId": "B" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "max (kube_pod_container_resource_limits{cluster=~\"$cluster\", namespace=~\"$namespace\", resource=\"memory\", container=~\"^(coder|provisionerd)$\"})", - "hide": false, - "legendFormat": "limit", - "range": true, - "refId": "C" - } - ], - "title": "Coder memory usage", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": true, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "bars", - "fillOpacity": 56, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": 60000, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - } - ] - }, - "unit": "bytes" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "requests" - }, - "properties": [ - { - "id": "custom.spanNulls", - "value": true - }, - { - "id": "custom.lineStyle", - "value": { - "dash": [10, 10], - "fill": "dash" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "limit" - }, - "properties": [ - { - "id": "custom.spanNulls", - "value": true - }, - { - "id": "custom.lineStyle", - "value": { - "dash": [10, 10], - "fill": "dash" - } - } - ] - } - ] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 9 - }, - "id": 24, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "sum by(pod) (-rate(container_network_transmit_bytes_total{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=~\"^coder-(provisioner-)?[a-z0-9]+-[a-z0-9]+$\"}[$__rate_interval]))", - "hide": false, - "legendFormat": "tx {{pod}}", - "range": true, - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "sum by(pod) (rate(container_network_receive_bytes_total{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=~\"^coder-(provisioner-)?[a-z0-9]+-[a-z0-9]+$\"}[$__rate_interval]))", - "hide": false, - "legendFormat": "rx {{pod}}", - "range": true, - "refId": "B" - } - ], - "title": "Coder Network TX/RX", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "axisSoftMin": 0, - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - } - ] - }, - "unit": "none" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "requests" - }, - "properties": [ - { - "id": "custom.spanNulls", - "value": true - }, - { - "id": "custom.lineStyle", - "value": { - "dash": [10, 10], - "fill": "dash" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "limit" - }, - "properties": [ - { - "id": "custom.spanNulls", - "value": true - }, - { - "id": "custom.lineStyle", - "value": { - "dash": [10, 10], - "fill": "dash" - } - } - ] - } - ] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 9 - }, - "id": 25, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "sum by(pod) (delta(kube_pod_container_status_restarts_total{cluster=~\"$cluster\", namespace=~\"$namespace\", container=~\"^(coder|provisionerd)$\"}[1m]))", - "hide": false, - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "Coder pod restarts", - "type": "timeseries" - }, - { - "datasource": { - "type": "stackdriver", - "uid": "${DS_GOOGLE_CLOUD MONITORING}" - }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "fixedColor": "#989898", - "mode": "fixed" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "fillOpacity": 80, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineWidth": 1, - "scaleDistribution": { - "type": "linear" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "blue", - "value": null - } - ] - }, - "unit": "none" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 17 - }, - "id": 50, - "options": { - "barRadius": 0, - "barWidth": 0.97, - "fullHighlight": false, - "groupWidth": 0.7, - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "orientation": "auto", - "showValue": "auto", - "stacking": "none", - "tooltip": { - "mode": "multi", - "sort": "none" - }, - "xTickLabelRotation": 0, - "xTickLabelSpacing": 200 - }, - "pluginVersion": "9.5.2", - "targets": [ - { - "datasource": { - "type": "stackdriver", - "uid": "${DS_GOOGLE_CLOUD MONITORING}" - }, - "queryType": "timeSeriesList", - "refId": "A", - "timeSeriesList": { - "alignmentPeriod": "+300s", - "crossSeriesReducer": "REDUCE_NONE", - "filters": [ - "resource.label.project_id", - "=", - "v2-loadtest", - "AND", - "resource.label.namespace_name", - "=", - "coder-big", - "AND", - "resource.label.container_name", - "=", - "coder", - "AND", - "resource.label.cluster_name", - "=", - "big", - "AND", - "resource.type", - "=", - "k8s_container", - "AND", - "resource.label.pod_name", - "!=~", - "coder-scaletest-.*", - "AND", - "resource.label.pod_name", - "=~", - "coder-.*", - "AND", - "metric.type", - "=", - "logging.googleapis.com/log_entry_count" - ], - "groupBys": [], - "perSeriesAligner": "ALIGN_SUM", - "preprocessor": "none", - "projectName": "v2-loadtest" - } - } - ], - "title": "Coder Logs Entries (All Levels)", - "type": "barchart" - }, - { - "datasource": { - "type": "googlecloud-logging-datasource", - "uid": "${DS_GOOGLE_CLOUD LOGGING :: V2-LOADTEST}" - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 17 - }, - "id": 51, - "options": { - "dedupStrategy": "none", - "enableLogDetails": true, - "prettifyLogMessage": false, - "showCommonLabels": false, - "showLabels": false, - "showTime": true, - "sortOrder": "Descending", - "wrapLogMessage": false - }, - "targets": [ - { - "datasource": { - "type": "googlecloud-logging-datasource", - "uid": "${DS_GOOGLE_CLOUD LOGGING :: V2-LOADTEST}" - }, - "projectId": "v2-loadtest", - "queryText": "resource.type=\"k8s_container\" AND\nresource.labels.cluster_name=\"big\" AND\nresource.labels.namespace_name=\"coder-big\" AND\nresource.labels.location=\"us-central1-a\" AND\nresource.labels.project_id=\"v2-loadtest\" AND\n(resource.labels.container_name=\"coder\" OR resource.labels.container_name=\"coder-provisionerd\") AND\njsonPayload.message!=\"\" AND\nseverity=\"ERROR\"", - "refId": "Error" - }, - { - "datasource": { - "type": "googlecloud-logging-datasource", - "uid": "${DS_GOOGLE_CLOUD LOGGING :: V2-LOADTEST}" - }, - "hide": false, - "projectId": "v2-loadtest", - "queryText": "resource.type=\"k8s_container\" AND\nresource.labels.cluster_name=\"big\" AND\nresource.labels.namespace_name=\"coder-big\" AND\nresource.labels.location=\"us-central1-a\" AND\nresource.labels.project_id=\"v2-loadtest\" AND\ntextPayload=~\"panic:.*\"", - "refId": "Panic" - } - ], - "title": "Coder Error Logs", - "type": "logs" - }, - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 25 - }, - "id": 29, - "panels": [], - "title": "Database", - "type": "row" - }, - { - "datasource": { - "type": "stackdriver", - "uid": "${DS_GOOGLE_CLOUD MONITORING}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "max": 1, - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "percentunit" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 26 - }, - "id": 52, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "stackdriver", - "uid": "${DS_GOOGLE_CLOUD MONITORING}" - }, - "queryType": "timeSeriesList", - "refId": "A", - "timeSeriesList": { - "alignmentPeriod": "cloud-monitoring-auto", - "crossSeriesReducer": "REDUCE_NONE", - "filters": [ - "resource.label.project_id", - "=", - "v2-loadtest", - "AND", - "metric.type", - "=", - "cloudsql.googleapis.com/database/cpu/utilization" - ], - "groupBys": ["resource.label.database_id"], - "perSeriesAligner": "ALIGN_NONE", - "preprocessor": "none", - "projectName": "v2-loadtest" - } - } - ], - "title": "DB CPU Util%", - "type": "timeseries" - }, - { - "datasource": { - "type": "stackdriver", - "uid": "${DS_GOOGLE_CLOUD MONITORING}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "max": 1, - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "percentunit" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 26 - }, - "id": 53, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "stackdriver", - "uid": "${DS_GOOGLE_CLOUD MONITORING}" - }, - "queryType": "timeSeriesList", - "refId": "A", - "timeSeriesList": { - "alignmentPeriod": "cloud-monitoring-auto", - "crossSeriesReducer": "REDUCE_NONE", - "filters": [ - "resource.label.project_id", - "=", - "v2-loadtest", - "AND", - "metric.type", - "=", - "cloudsql.googleapis.com/database/memory/utilization" - ], - "groupBys": [], - "perSeriesAligner": "ALIGN_NONE", - "preprocessor": "none", - "projectName": "v2-loadtest" - } - } - ], - "title": "DB Mem Util%", - "type": "timeseries" - }, - { - "datasource": { - "type": "stackdriver", - "uid": "${DS_GOOGLE_CLOUD MONITORING}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "none" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 34 - }, - "id": 54, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "stackdriver", - "uid": "${DS_GOOGLE_CLOUD MONITORING}" - }, - "queryType": "timeSeriesList", - "refId": "A", - "timeSeriesList": { - "alignmentPeriod": "+60s", - "crossSeriesReducer": "REDUCE_NONE", - "filters": [ - "resource.label.project_id", - "=", - "v2-loadtest", - "AND", - "metric.type", - "=", - "cloudsql.googleapis.com/database/disk/read_ops_count" - ], - "groupBys": [], - "perSeriesAligner": "ALIGN_DELTA", - "preprocessor": "none", - "projectName": "v2-loadtest" - } - } - ], - "title": "DB Disk Read I/O", - "type": "timeseries" - }, - { - "datasource": { - "type": "stackdriver", - "uid": "${DS_GOOGLE_CLOUD MONITORING}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "none" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 34 - }, - "id": 55, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "stackdriver", - "uid": "${DS_GOOGLE_CLOUD MONITORING}" - }, - "queryType": "timeSeriesList", - "refId": "A", - "timeSeriesList": { - "alignmentPeriod": "cloud-monitoring-auto", - "crossSeriesReducer": "REDUCE_NONE", - "filters": [ - "resource.label.project_id", - "=", - "v2-loadtest", - "AND", - "metric.type", - "=", - "cloudsql.googleapis.com/database/disk/write_ops_count" - ], - "groupBys": [], - "perSeriesAligner": "ALIGN_NONE", - "preprocessor": "rate", - "projectName": "v2-loadtest" - } - } - ], - "title": "DB Disk Write I/O", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "description": "LOGARITHMIC Y AXIS", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "bars", - "fillOpacity": 100, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "log": 2, - "type": "log" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "normal" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "none" - }, - "overrides": [] - }, - "gridPos": { - "h": 16, - "w": 12, - "x": 0, - "y": 42 - }, - "id": 36, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "sum(rate(pg_stat_database_tup_inserted{cluster=~\"$cluster\", datname=\"${cluster}-coder\"}[$__rate_interval]))", - "hide": false, - "legendFormat": "INSERT", - "range": true, - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "sum(rate(pg_stat_database_tup_updated{cluster=~\"$cluster\", datname=\"${cluster}-coder\"}[$__rate_interval]))", - "hide": false, - "legendFormat": "UPDATE", - "range": true, - "refId": "B" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "sum(rate(pg_stat_database_tup_deleted{cluster=~\"$cluster\", datname=\"${cluster}-coder\"}[$__rate_interval]))", - "hide": false, - "legendFormat": "DELETE", - "range": true, - "refId": "C" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "sum(rate(pg_stat_database_tup_returned{cluster=~\"$cluster\", datname=\"${cluster}-coder\"}[$__rate_interval]))", - "hide": false, - "legendFormat": "RETURN", - "range": true, - "refId": "D" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "sum(rate(pg_stat_database_tup_fetched{cluster=~\"$cluster\", datname=\"${cluster}-coder\"}[$__rate_interval]))", - "hide": false, - "legendFormat": "FETCH", - "range": true, - "refId": "E" - } - ], - "title": "DB insert/update/delete/return", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "bars", - "fillOpacity": 100, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "normal" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "none" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 42 - }, - "id": 39, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "pg_stat_activity_count{datname=~\"${cluster}-coder\", cluster=~\"${cluster}\", state=\"active\"} !=0", - "hide": false, - "legendFormat": "active", - "range": true, - "refId": "C" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "pg_stat_activity_count{datname=~\"${cluster}-coder\", cluster=~\"${cluster}\", state=\"idle\"} !=0", - "hide": false, - "legendFormat": "idle", - "range": true, - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "pg_stat_activity_count{datname=~\"${cluster}-coder\", cluster=~\"${cluster}\", state=\"idle in transaction\"} != 0", - "hide": false, - "legendFormat": "idle_tx", - "range": true, - "refId": "B" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "pg_stat_activity_count{datname=~\"${cluster}-coder\", cluster=~\"${cluster}\", state=\"disabled\"} != 0", - "hide": false, - "legendFormat": "disabled", - "range": true, - "refId": "D" - } - ], - "title": "DB conns", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "none" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 50 - }, - "id": 37, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "sum(rate(pg_stat_database_xact_commit{cluster=~\"$cluster\", datname=\"${cluster}-coder\"}[$__rate_interval]))", - "hide": false, - "legendFormat": "commit", - "range": true, - "refId": "B" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "sum(rate(pg_stat_database_xact_rollback{cluster=~\"$cluster\", datname=\"${cluster}-coder\"}[$__rate_interval]))", - "hide": false, - "legendFormat": "rollback", - "range": true, - "refId": "A" - } - ], - "title": "DB TX/s", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "custom": { - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "scaleDistribution": { - "type": "linear" - } - } - }, - "overrides": [] - }, - "gridPos": { - "h": 26, - "w": 12, - "x": 0, - "y": 58 - }, - "id": 30, - "options": { - "calculate": false, - "cellGap": 1, - "cellValues": { - "unit": "s" - }, - "color": { - "exponent": 0.5, - "fill": "dark-orange", - "min": 0, - "mode": "scheme", - "reverse": false, - "scale": "exponential", - "scheme": "Viridis", - "steps": 64 - }, - "exemplars": { - "color": "rgba(255,0,255,0.7)" - }, - "filterValues": { - "le": 1e-9 - }, - "legend": { - "show": true - }, - "rowsFrame": { - "layout": "auto" - }, - "tooltip": { - "mode": "single", - "showColorScale": false, - "yHistogram": false - }, - "yAxis": { - "axisPlacement": "left", - "reverse": false - } - }, - "pluginVersion": "11.1.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "histogram_quantile(0.95, sum by(le, query) (rate(coderd_db_query_latencies_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$pod\"}[$__rate_interval])))", - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "sqlQuerier P95 execution timing", - "type": "heatmap" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "custom": { - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "scaleDistribution": { - "type": "linear" - } - } - }, - "overrides": [] - }, - "gridPos": { - "h": 26, - "w": 12, - "x": 12, - "y": 58 - }, - "id": 31, - "options": { - "calculate": false, - "cellGap": 1, - "cellValues": { - "unit": "reqps" - }, - "color": { - "exponent": 0.5, - "fill": "dark-orange", - "min": 0, - "mode": "scheme", - "reverse": false, - "scale": "exponential", - "scheme": "Viridis", - "steps": 64 - }, - "exemplars": { - "color": "rgba(255,0,255,0.7)" - }, - "filterValues": { - "le": 1e-9 - }, - "legend": { - "show": true - }, - "rowsFrame": { - "layout": "auto" - }, - "tooltip": { - "mode": "single", - "showColorScale": false, - "yHistogram": false - }, - "yAxis": { - "axisPlacement": "left", - "reverse": false - } - }, - "pluginVersion": "11.1.0", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "sum by(le, query) (rate(coderd_db_query_latencies_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$pod\"}[$__rate_interval]))", - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "sqlQuerier execution count", - "type": "heatmap" - }, - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 84 - }, - "id": 16, - "panels": [], - "title": "HTTP Requests", - "type": "row" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "reqps" - }, - "overrides": [] - }, - "gridPos": { - "h": 11, - "w": 12, - "x": 0, - "y": 85 - }, - "id": 45, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "exemplar": false, - "expr": "sum by(pod) (rate(coderd_api_requests_processed_total{cluster=\"$cluster\", namespace=~\"$namespace\", pod=~\"$pod\"}[$__rate_interval]))", - "instant": true, - "key": "Q-2eb2f8ac-845d-462d-9bb0-b98334fbfd4a-0", - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "API Requests by pod", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 11, - "w": 12, - "x": 12, - "y": 85 - }, - "id": 44, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "exemplar": false, - "expr": "sum(rate(coderd_api_requests_processed_total{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=~\"$pod\", code=~\"5..\"}[$__rate_interval]))", - "instant": true, - "key": "Q-2eb2f8ac-845d-462d-9bb0-b98334fbfd4a-0", - "legendFormat": "5xx", - "range": true, - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "sum(rate(coderd_api_requests_processed_total{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=~\"$pod\", code=~\"4..\"}[$__rate_interval]))", - "instant": true, - "key": "Q-fe3b7389-28e7-4b2c-90ef-3b1490f99528-1", - "legendFormat": "4xx", - "range": true, - "refId": "B" - } - ], - "title": "API Error Rate", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "custom": { - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "scaleDistribution": { - "type": "linear" - } - } - }, - "overrides": [] - }, - "gridPos": { - "h": 10, - "w": 24, - "x": 0, - "y": 96 - }, - "id": 4, - "options": { - "calculate": false, - "cellGap": 1, - "color": { - "exponent": 0.5, - "fill": "dark-orange", - "min": 0, - "mode": "scheme", - "reverse": false, - "scale": "exponential", - "scheme": "Viridis", - "steps": 64 - }, - "exemplars": { - "color": "rgba(255,0,255,0.7)" - }, - "filterValues": { - "le": 1e-9 - }, - "legend": { - "show": true - }, - "rowsFrame": { - "layout": "auto" - }, - "tooltip": { - "show": true, - "yHistogram": false - }, - "yAxis": { - "axisPlacement": "left", - "reverse": false - } - }, - "pluginVersion": "9.5.2", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "sum by (code,method) (rate(coderd_api_requests_processed_total{cluster=~\"$cluster\",namespace=~\"$namespace\",pod=~\"$pod\",container=\"coder\",code!=\"0\"}[$__rate_interval]))", - "legendFormat": "{{method}} {{code}}", - "range": true, - "refId": "A" - } - ], - "title": "API requests/sec by response, method", - "type": "heatmap" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "custom": { - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "scaleDistribution": { - "type": "linear" - } - } - }, - "overrides": [] - }, - "gridPos": { - "h": 18, - "w": 12, - "x": 0, - "y": 106 - }, - "id": 33, - "options": { - "calculate": false, - "cellGap": 1, - "cellValues": { - "unit": "s" - }, - "color": { - "exponent": 0.5, - "fill": "dark-orange", - "mode": "scheme", - "reverse": false, - "scale": "exponential", - "scheme": "Viridis", - "steps": 64 - }, - "exemplars": { - "color": "rgba(255,0,255,0.7)" - }, - "filterValues": { - "le": 1e-9 - }, - "legend": { - "show": true - }, - "rowsFrame": { - "layout": "auto" - }, - "tooltip": { - "show": true, - "yHistogram": false - }, - "yAxis": { - "axisPlacement": "left", - "reverse": false - } - }, - "pluginVersion": "9.5.2", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "histogram_quantile(0.95, sum by(le, path) (rate(coderd_api_request_latencies_seconds_bucket{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=~\"$pod\", path=~\"^/api/v2/.*\"}[$__rate_interval])))", - "interval": "", - "legendFormat": "{{path}}", - "range": true, - "refId": "A" - } - ], - "title": "API Request Latency P95", - "type": "heatmap" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "custom": { - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "scaleDistribution": { - "type": "linear" - } - } - }, - "overrides": [] - }, - "gridPos": { - "h": 18, - "w": 12, - "x": 12, - "y": 106 - }, - "id": 34, - "options": { - "calculate": false, - "cellGap": 1, - "color": { - "exponent": 0.5, - "fill": "dark-orange", - "mode": "scheme", - "reverse": false, - "scale": "exponential", - "scheme": "Viridis", - "steps": 64 - }, - "exemplars": { - "color": "rgba(255,0,255,0.7)" - }, - "filterValues": { - "le": 1e-9 - }, - "legend": { - "show": true - }, - "rowsFrame": { - "layout": "auto" - }, - "tooltip": { - "show": true, - "yHistogram": false - }, - "yAxis": { - "axisPlacement": "left", - "reverse": false - } - }, - "pluginVersion": "9.5.2", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "sum by(method, path) (rate(coderd_api_request_latencies_seconds_count{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=~\"$pod\", path=~\"^/api/v2/.*\"}[$__rate_interval]))", - "interval": "", - "legendFormat": "{{method}} {{path}}", - "range": true, - "refId": "A" - } - ], - "title": "API Requests", - "type": "heatmap" - }, - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 124 - }, - "id": 40, - "panels": [], - "title": "Workspace Resources", - "type": "row" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 1, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "limit" - }, - "properties": [ - { - "id": "custom.drawStyle", - "value": "line" - }, - { - "id": "custom.lineStyle", - "value": { - "dash": [10, 10], - "fill": "dash" - } - } - ] - } - ] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 125 - }, - "id": 41, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "max(kube_pod_container_resource_limits{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=~\"coder-scaletest-.*-scaletest-.*\", pod!=\"coder-scaletest-runner-scaletest-runner\", resource=\"cpu\"})", - "legendFormat": "limit", - "range": true, - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "avg(rate(container_cpu_usage_seconds_total{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=~\"coder-scaletest-.*-scaletest-.*\", pod!=\"coder-scaletest-runner-scaletest-runner\", container=\"dev\"}[$__rate_interval]))", - "hide": false, - "legendFormat": "__auto", - "range": true, - "refId": "B" - } - ], - "title": "Scaletest Workspace CPU Usage (Avg)", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": true, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "smooth", - "lineWidth": 1, - "pointSize": 1, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": 60000, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - } - ] - }, - "unit": "binBps" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "limit" - }, - "properties": [ - { - "id": "custom.drawStyle", - "value": "line" - }, - { - "id": "custom.lineStyle", - "value": { - "dash": [10, 10], - "fill": "dash" - } - } - ] - } - ] - }, - "gridPos": { - "h": 16, - "w": 12, - "x": 12, - "y": 125 - }, - "id": 43, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "sum(rate(container_network_receive_bytes_total{cluster=~\"${cluster}\", namespace=~\"${namespace}\", pod=~\"coder-scaletest-.*-scaletest-.*\", pod!=\"coder-scaletest-runner-scaletest-runner\"}[$__rate_interval]))", - "format": "time_series", - "hide": false, - "legendFormat": "rx", - "range": true, - "refId": "B" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "sum(rate(container_network_transmit_bytes_total{cluster=~\"${cluster}\", namespace=~\"${namespace}\", pod=~\"coder-scaletest-.*-scaletest-.*\", pod!=\"coder-scaletest-runner-scaletest-runner\"}[$__rate_interval])) * -1", - "hide": false, - "legendFormat": "tx {{pod}}", - "range": true, - "refId": "A" - } - ], - "title": "Scaletest Workspace Network Usage (Sum)", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 1, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - } - ] - }, - "unit": "bytes" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "limit" - }, - "properties": [ - { - "id": "custom.drawStyle", - "value": "line" - }, - { - "id": "custom.lineStyle", - "value": { - "dash": [10, 10], - "fill": "dash" - } - } - ] - } - ] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 133 - }, - "id": 42, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "max(kube_pod_container_resource_limits{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=~\"coder-scaletest-.*-scaletest-.*\", pod!=\"coder-scaletest-runner-scaletest-runner\", resource=\"memory\"})", - "legendFormat": "limit", - "range": true, - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "avg(container_memory_usage_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=~\"coder-scaletest-.*-scaletest-.*\", pod!=\"coder-scaletest-runner-scaletest-runner\", container!=\"\"})", - "hide": false, - "legendFormat": "__auto", - "range": true, - "refId": "B" - } - ], - "title": "Scaletest Workspace Memory Usage (Avg)", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": true, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "smooth", - "lineWidth": 1, - "pointSize": 1, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": 60000, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - } - ] - }, - "unit": "none" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "limit" - }, - "properties": [ - { - "id": "custom.drawStyle", - "value": "line" - }, - { - "id": "custom.lineStyle", - "value": { - "dash": [10, 10], - "fill": "dash" - } - } - ] - } - ] - }, - "gridPos": { - "h": 16, - "w": 12, - "x": 12, - "y": 141 - }, - "id": 56, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "sum(rate(container_network_receive_errors_total{cluster=~\"${cluster}\", namespace=~\"${namespace}\", pod=~\"coder-scaletest-.*-scaletest-.*\", pod!=\"coder-scaletest-runner-scaletest-runner\"}[$__rate_interval]))", - "format": "time_series", - "hide": false, - "legendFormat": "rx errs {{pod}}", - "range": true, - "refId": "B" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "sum(rate(container_network_transmit_errors_total{cluster=~\"${cluster}\", namespace=~\"${namespace}\", pod=~\"coder-scaletest-.*-scaletest-.*\", pod!=\"coder-scaletest-runner-scaletest-runner\"}[$__rate_interval])) * -1", - "hide": false, - "legendFormat": "tx errs {{pod}}", - "range": true, - "refId": "A" - } - ], - "title": "Scaletest Workspace Network RX/TX errs (Sum)", - "type": "timeseries" - }, - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 157 - }, - "id": 18, - "panels": [], - "title": "Workspace Agents", - "type": "row" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": true, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "smooth", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": 3600000, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "bytes" - }, - "overrides": [] - }, - "gridPos": { - "h": 18, - "w": 12, - "x": 0, - "y": 158 - }, - "id": 20, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "pluginVersion": "9.5.2", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "sum(rate(coderd_agentstats_rx_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=~\"$pod\"}[$__rate_interval]))", - "legendFormat": "rx", - "range": true, - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "sum(rate(coderd_agentstats_tx_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=~\"$pod\"}[$__rate_interval])) * -1", - "hide": false, - "legendFormat": "tx", - "range": true, - "refId": "B" - } - ], - "title": "Agent Connection RX/TX", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 18, - "gradientMode": "hue", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 3, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "s" - }, - "overrides": [] - }, - "gridPos": { - "h": 18, - "w": 12, - "x": 12, - "y": 158 - }, - "id": 38, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "pluginVersion": "9.5.2", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "quantile(0.5, coderd_agents_connection_latencies_seconds{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=~\"$pod\"})", - "legendFormat": "p50", - "range": true, - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "quantile(0.95, coderd_agents_connection_latencies_seconds{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=~\"$pod\"})", - "hide": false, - "legendFormat": "p95", - "range": true, - "refId": "B" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "quantile(0.99, coderd_agents_connection_latencies_seconds{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=~\"$pod\"})", - "hide": false, - "legendFormat": "p99", - "range": true, - "refId": "C" - } - ], - "title": "Agent Connection Latency P50/95/99", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "none" - }, - "overrides": [] - }, - "gridPos": { - "h": 9, - "w": 12, - "x": 0, - "y": 176 - }, - "id": 3, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "sum by(pod) (coderd_api_concurrent_websockets{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=~\"$pod\", container=\"coder\"})", - "format": "time_series", - "interval": "", - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "Websocket Connections", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "none" - }, - "overrides": [] - }, - "gridPos": { - "h": 9, - "w": 12, - "x": 12, - "y": 176 - }, - "id": 19, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "sum by (pod) (coderd_agents_connections{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=~\"$pod\"})", - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "Agent Connections", - "type": "timeseries" - }, - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 185 - }, - "id": 14, - "panels": [], - "title": "Workspace Traffic", - "type": "row" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": true, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 22, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "binBps" - }, - "overrides": [] - }, - "gridPos": { - "h": 16, - "w": 12, - "x": 0, - "y": 186 - }, - "id": 11, - "options": { - "legend": { - "calcs": [], - "displayMode": "table", - "placement": "right", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "pluginVersion": "9.5.2", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "sum by(pod) (rate(coderd_scaletest_bytes_written_total{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval])) * -1", - "legendFormat": "tx inside container", - "range": true, - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "sum by(pod) (rate(coderd_scaletest_bytes_read_total{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval]))", - "hide": false, - "legendFormat": "rx inside container", - "range": true, - "refId": "B" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "sum by(pod) (rate(container_network_receive_bytes_total{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=\"coder-scaletest-workspace-traffic\"}[$__rate_interval])) * 1", - "hide": false, - "legendFormat": "rx outside container", - "range": true, - "refId": "C" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "sum by(pod) (rate(container_network_transmit_bytes_total{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=\"coder-scaletest-workspace-traffic\"}[$__rate_interval])) * -1", - "hide": false, - "legendFormat": "tx outside container", - "range": true, - "refId": "D" - } - ], - "title": "Workspace Traffic bytes TX/RX", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 3, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "s" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 186 - }, - "id": 12, - "options": { - "legend": { - "calcs": [], - "displayMode": "table", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "pluginVersion": "9.5.2", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "histogram_quantile(0.95, sum by(le, pod) (rate(coderd_scaletest_read_latency_seconds_bucket{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval])))", - "hide": false, - "legendFormat": "__auto", - "range": true, - "refId": "B" - } - ], - "title": "Workspace Traffic read latency P95", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "s" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 194 - }, - "id": 32, - "options": { - "legend": { - "calcs": [], - "displayMode": "table", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "pluginVersion": "9.5.2", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "histogram_quantile(0.95, sum by(le, pod) (rate(coderd_scaletest_write_latency_seconds_bucket{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval])))", - "hide": false, - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "Workspace Traffic write latency P95", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 202 - }, - "id": 13, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "pluginVersion": "9.5.2", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "sum by(pod) (rate(coderd_scaletest_read_errors_total{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval]))", - "hide": false, - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "Workspace Traffic Read errors", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 202 - }, - "id": 28, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "pluginVersion": "9.5.2", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "sum by(pod) (rate(coderd_scaletest_write_errors_total{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval]))", - "hide": false, - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "Workspace Traffic Write errors", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "requests" - }, - "properties": [ - { - "id": "custom.spanNulls", - "value": true - }, - { - "id": "custom.lineStyle", - "value": { - "dash": [10, 10], - "fill": "dash" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "limit" - }, - "properties": [ - { - "id": "custom.spanNulls", - "value": true - }, - { - "id": "custom.lineStyle", - "value": { - "dash": [10, 10], - "fill": "dash" - } - } - ] - } - ] - }, - "gridPos": { - "h": 8, - "w": 8, - "x": 0, - "y": 210 - }, - "id": 22, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "sum by(pod) (rate(container_cpu_usage_seconds_total{cluster=~\"$cluster\", namespace=~\"$namespace\",pod=\"coder-scaletest-runner-scaletest-runner\", container=\"dev\"}[$__rate_interval]))", - "hide": false, - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "Traffic Generation CPU usage", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - } - ] - }, - "unit": "bytes" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "requests" - }, - "properties": [ - { - "id": "custom.spanNulls", - "value": true - }, - { - "id": "custom.lineStyle", - "value": { - "dash": [10, 10], - "fill": "dash" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "limit" - }, - "properties": [ - { - "id": "custom.spanNulls", - "value": true - }, - { - "id": "custom.lineStyle", - "value": { - "dash": [10, 10], - "fill": "dash" - } - } - ] - } - ] - }, - "gridPos": { - "h": 8, - "w": 8, - "x": 8, - "y": 210 - }, - "id": 23, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "sum by(pod) (container_memory_working_set_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\",pod=\"coder-scaletest-runner-scaletest-runner\",container=\"dev\"})", - "hide": false, - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "Traffic Generation Memory usage", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "axisSoftMin": 0, - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - } - ] - }, - "unit": "none" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "requests" - }, - "properties": [ - { - "id": "custom.spanNulls", - "value": true - }, - { - "id": "custom.lineStyle", - "value": { - "dash": [10, 10], - "fill": "dash" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "limit" - }, - "properties": [ - { - "id": "custom.spanNulls", - "value": true - }, - { - "id": "custom.lineStyle", - "value": { - "dash": [10, 10], - "fill": "dash" - } - } - ] - } - ] - }, - "gridPos": { - "h": 8, - "w": 8, - "x": 16, - "y": 210 - }, - "id": 26, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "sum by(pod) (increase(kube_pod_container_status_restarts_total{cluster=~\"$cluster\", namespace=~\"$namespace\",pod=\"coder-scaletest-runner-scaletest-runner\"}[$__rate_interval]))", - "hide": false, - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "Traffic generation pod restarts", - "type": "timeseries" - }, - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 218 - }, - "id": 46, - "panels": [], - "title": "Scaletest Dashboard Actions", - "type": "row" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "log": 2, - "type": "log" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "s" - }, - "overrides": [] - }, - "gridPos": { - "h": 19, - "w": 12, - "x": 0, - "y": 219 - }, - "id": 47, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "histogram_quantile(0.95, sum by(le, action) (rate(coderd_scaletest_dashboard_duration_seconds_bucket{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=~\"$pod\"}[$__rate_interval])))", - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "Dashboard Actions Duration P95", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "bars", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "normal" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "none" - }, - "overrides": [] - }, - "gridPos": { - "h": 19, - "w": 12, - "x": 12, - "y": 219 - }, - "id": 49, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "sum by(le, action) (rate(coderd_scaletest_dashboard_errors_total{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=~\"$pod\"}[$__rate_interval]))", - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "Dashboard Actions Errors", - "type": "timeseries" - }, - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 238 - }, - "id": 17, - "panels": [], - "title": "Internals", - "type": "row" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 31, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "s" - }, - "overrides": [] - }, - "gridPos": { - "h": 7, - "w": 12, - "x": 0, - "y": 239 - }, - "id": 5, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "histogram_quantile(0.5, sum by(le) (rate(coderd_authz_authorize_duration_seconds_bucket{cluster=~\"$cluster\",namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])))", - "interval": "", - "legendFormat": "p50", - "range": true, - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "histogram_quantile(0.9, sum by(le) (rate(coderd_authz_authorize_duration_seconds_bucket{cluster=~\"$cluster\",namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])))", - "hide": false, - "interval": "", - "legendFormat": "p90", - "range": true, - "refId": "B" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "histogram_quantile(0.95, sum by(le) (rate(coderd_authz_authorize_duration_seconds_bucket{cluster=~\"$cluster\",namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])))", - "hide": false, - "interval": "", - "legendFormat": "p95", - "range": true, - "refId": "C" - } - ], - "title": "AuthZ Duration", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 31, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "s" - }, - "overrides": [] - }, - "gridPos": { - "h": 7, - "w": 12, - "x": 12, - "y": 239 - }, - "id": 6, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "histogram_quantile(0.5, sum by(le, pod) (rate(coderd_provisionerd_job_timings_seconds_bucket{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval])))", - "interval": "", - "legendFormat": "p50-{{pod}}", - "range": true, - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "histogram_quantile(0.9, sum by(le, pod) (rate(coderd_provisionerd_job_timings_seconds_bucket{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval])))", - "hide": false, - "interval": "", - "legendFormat": "p90-{{pod}}", - "range": true, - "refId": "B" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "histogram_quantile(0.95, sum by(le, pod) (rate(coderd_provisionerd_job_timings_seconds_bucket{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval])))", - "hide": false, - "interval": "", - "legendFormat": "p95-{{pod}}", - "range": true, - "refId": "C" - } - ], - "title": "Provisioner Job Timings", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "bars", - "fillOpacity": 69, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "normal" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 246 - }, - "id": 8, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "sum by(status, pod) (coderd_workspace_builds_total{cluster=~\"$cluster\", namespace=~\"$namespace\", workspace_transition=\"START\"})", - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "Total Workspace Builds", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "bars", - "fillOpacity": 69, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "normal" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "daemons" - }, - "properties": [ - { - "id": "custom.drawStyle", - "value": "line" - }, - { - "id": "custom.fillOpacity", - "value": 0 - }, - { - "id": "color", - "value": { - "mode": "continuous-BlYlRd" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "external_daemons" - }, - "properties": [ - { - "id": "custom.drawStyle", - "value": "line" - }, - { - "id": "custom.fillOpacity", - "value": 0 - } - ] - } - ] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 246 - }, - "id": 35, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "sum by(status, container) (coderd_provisionerd_jobs_current{cluster=~\"$cluster\", namespace=~\"$namespace\", container=~\"^(coder|provisionerd)$\"})", - "legendFormat": "__auto", - "range": true, - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "sum by(status, container) (coderd_provisionerd_num_daemons{cluster=~\"$cluster\", namespace=~\"$namespace\", container=~\"^(coder|provisionerd)$\"})", - "hide": false, - "legendFormat": "builtin_daemons", - "range": true, - "refId": "B" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "sum(kube_pod_container_status_running {cluster=~\"$cluster\", namespace=~\"coder-big\", pod=~\"coder-provisioner-.*\"})", - "hide": false, - "legendFormat": "external_daemons", - "range": true, - "refId": "C" - } - ], - "title": "Concurrent Provisioner Jobs", - "type": "timeseries" - } - ], - "refresh": false, - "schemaVersion": 39, - "tags": [], - "templating": { - "list": [ - { - "allValue": ".*", - "current": {}, - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "definition": "label_values(coderd_api_concurrent_requests,cluster)", - "hide": 0, - "includeAll": false, - "label": "cluster", - "multi": false, - "name": "cluster", - "options": [], - "query": { - "query": "label_values(coderd_api_concurrent_requests,cluster)", - "refId": "PrometheusVariableQueryEditor-VariableQuery" - }, - "refresh": 1, - "regex": "", - "skipUrlSync": false, - "sort": 1, - "type": "query" - }, - { - "allValue": ".*", - "current": {}, - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "definition": "label_values(coderd_api_concurrent_requests,namespace)", - "hide": 0, - "includeAll": false, - "label": "namespace", - "multi": false, - "name": "namespace", - "options": [], - "query": { - "query": "label_values(coderd_api_concurrent_requests,namespace)", - "refId": "PrometheusVariableQueryEditor-VariableQuery" - }, - "refresh": 1, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "type": "query" - }, - { - "allValue": ".*", - "current": {}, - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "definition": "label_values(coderd_api_concurrent_requests,pod)", - "hide": 0, - "includeAll": true, - "label": "pod", - "multi": false, - "name": "pod", - "options": [], - "query": { - "query": "label_values(coderd_api_concurrent_requests,pod)", - "refId": "PrometheusVariableQueryEditor-VariableQuery" - }, - "refresh": 1, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "type": "query" - } - ] - }, - "time": { - "from": "now-6h", - "to": "now" - }, - "timepicker": {}, - "timezone": "", - "title": "CoderV2 Loadtest Dashboard", - "uid": "qLVSTR-Vz", - "version": 254, - "weekStart": "" + "__inputs": [ + { + "name": "DS_PROMETHEUS", + "label": "Prometheus", + "description": "", + "type": "datasource", + "pluginId": "prometheus", + "pluginName": "Prometheus" + }, + { + "name": "DS_GOOGLE_CLOUD MONITORING", + "label": "Google Cloud Monitoring", + "description": "", + "type": "datasource", + "pluginId": "stackdriver", + "pluginName": "Google Cloud Monitoring" + }, + { + "name": "DS_GOOGLE_CLOUD LOGGING :: V2-LOADTEST", + "label": "Google Cloud Logging :: v2-loadtest", + "description": "", + "type": "datasource", + "pluginId": "googlecloud-logging-datasource", + "pluginName": "Google Cloud Logging" + } + ], + "__elements": {}, + "__requires": [ + { + "type": "panel", + "id": "barchart", + "name": "Bar chart", + "version": "" + }, + { + "type": "datasource", + "id": "googlecloud-logging-datasource", + "name": "Google Cloud Logging", + "version": "1.3.0" + }, + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "11.1.0" + }, + { + "type": "panel", + "id": "heatmap", + "name": "Heatmap", + "version": "" + }, + { + "type": "panel", + "id": "logs", + "name": "Logs", + "version": "" + }, + { + "type": "datasource", + "id": "prometheus", + "name": "Prometheus", + "version": "1.0.0" + }, + { + "type": "datasource", + "id": "stackdriver", + "name": "Google Cloud Monitoring", + "version": "11.1.0" + }, + { + "type": "panel", + "id": "timeseries", + "name": "Time series", + "version": "" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "target": { + "limit": 100, + "matchAny": false, + "tags": [], + "type": "dashboard" + }, + "type": "dashboard" + }, + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "enable": true, + "iconColor": "red", + "name": "Scaletest Error", + "target": { + "refId": "Anno", + "tags": ["scaletest", "runner", "error"], + "type": "tags" + } + }, + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "enable": true, + "iconColor": "green", + "name": "Scaletest Phase", + "target": { + "refId": "Anno", + "tags": ["scaletest", "runner", "phase-default"], + "type": "tags" + } + }, + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "enable": true, + "iconColor": "transparent", + "name": "Scaletest Phase (Wait)", + "target": { + "refId": "Anno", + "tags": ["scaletest", "runner", "phase-wait"], + "type": "tags" + } + }, + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "enable": true, + "iconColor": "blue", + "name": "Scaletest Status", + "target": { + "refId": "Anno", + "tags": ["scaletest", "runner", "status"], + "type": "tags" + } + }, + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "enable": true, + "iconColor": "dark-green", + "name": "Concurrent Scenarios", + "target": { + "refId": "Anno", + "tags": ["scaletest", "runner", "scenario"], + "type": "tags" + } + }, + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "enable": true, + "iconColor": "semi-dark-orange", + "name": "Greedy agent", + "target": { + "refId": "Anno", + "tags": ["scaletest", "runner", "greedy_agent"], + "type": "tags" + } + }, + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "enable": false, + "iconColor": "super-light-purple", + "name": "Scaletest Runner Workspace", + "target": { + "refId": "Anno", + "tags": ["scaletest", "runner", "workspace"], + "type": "tags" + } + }, + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "enable": false, + "iconColor": "super-light-orange", + "name": "Pprof", + "target": { + "limit": 100, + "matchAny": false, + "tags": ["scaletest", "runner", "pprof"], + "type": "tags" + } + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 1, + "id": null, + "links": [], + "liveNow": false, + "panels": [ + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 15, + "panels": [], + "title": "Control Plane Resources", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": 60000, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "requests" + }, + "properties": [ + { + "id": "custom.spanNulls", + "value": true + }, + { + "id": "custom.lineStyle", + "value": { + "dash": [10, 10], + "fill": "dash" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "limit" + }, + "properties": [ + { + "id": "custom.spanNulls", + "value": true + }, + { + "id": "custom.lineStyle", + "value": { + "dash": [10, 10], + "fill": "dash" + } + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 1 + }, + "id": 9, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum by(pod) (rate(container_cpu_usage_seconds_total{cluster=~\"$cluster\", namespace=~\"$namespace\", container=~\"^(coder|provisionerd)$\"}[$__rate_interval])) ", + "hide": false, + "legendFormat": "{{label_name}}", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "max (kube_pod_container_resource_requests{cluster=~\"$cluster\", namespace=~\"$namespace\", resource=\"cpu\", container=~\"^(coder|provisionerd)$\"})", + "hide": false, + "instant": false, + "legendFormat": "requests", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "max (kube_pod_container_resource_limits{cluster=~\"$cluster\", namespace=~\"$namespace\", resource=\"cpu\", container=~\"^(coder|provisionerd)$\"})", + "hide": false, + "instant": false, + "legendFormat": "limit", + "range": true, + "refId": "C" + } + ], + "title": "Coder CPU usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "axisSoftMin": 0, + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": 60000, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "bytes" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "requests" + }, + "properties": [ + { + "id": "custom.spanNulls", + "value": true + }, + { + "id": "custom.lineStyle", + "value": { + "dash": [10, 10], + "fill": "dash" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "limit" + }, + "properties": [ + { + "id": "custom.spanNulls", + "value": true + }, + { + "id": "custom.lineStyle", + "value": { + "dash": [10, 10], + "fill": "dash" + } + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 1 + }, + "id": 10, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum by(pod) (container_memory_working_set_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\", container=~\"^(coder|provisionerd)$\"})", + "hide": false, + "legendFormat": "__auto", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "max (kube_pod_container_resource_requests{cluster=~\"$cluster\", namespace=~\"$namespace\", resource=\"memory\", container=~\"^(coder|provisionerd)$\"})", + "hide": false, + "legendFormat": "requests", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "max (kube_pod_container_resource_limits{cluster=~\"$cluster\", namespace=~\"$namespace\", resource=\"memory\", container=~\"^(coder|provisionerd)$\"})", + "hide": false, + "legendFormat": "limit", + "range": true, + "refId": "C" + } + ], + "title": "Coder memory usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": true, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "bars", + "fillOpacity": 56, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": 60000, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "bytes" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "requests" + }, + "properties": [ + { + "id": "custom.spanNulls", + "value": true + }, + { + "id": "custom.lineStyle", + "value": { + "dash": [10, 10], + "fill": "dash" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "limit" + }, + "properties": [ + { + "id": "custom.spanNulls", + "value": true + }, + { + "id": "custom.lineStyle", + "value": { + "dash": [10, 10], + "fill": "dash" + } + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 9 + }, + "id": 24, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum by(pod) (-rate(container_network_transmit_bytes_total{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=~\"^coder-(provisioner-)?[a-z0-9]+-[a-z0-9]+$\"}[$__rate_interval]))", + "hide": false, + "legendFormat": "tx {{pod}}", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum by(pod) (rate(container_network_receive_bytes_total{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=~\"^coder-(provisioner-)?[a-z0-9]+-[a-z0-9]+$\"}[$__rate_interval]))", + "hide": false, + "legendFormat": "rx {{pod}}", + "range": true, + "refId": "B" + } + ], + "title": "Coder Network TX/RX", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "axisSoftMin": 0, + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "requests" + }, + "properties": [ + { + "id": "custom.spanNulls", + "value": true + }, + { + "id": "custom.lineStyle", + "value": { + "dash": [10, 10], + "fill": "dash" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "limit" + }, + "properties": [ + { + "id": "custom.spanNulls", + "value": true + }, + { + "id": "custom.lineStyle", + "value": { + "dash": [10, 10], + "fill": "dash" + } + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 9 + }, + "id": 25, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum by(pod) (delta(kube_pod_container_status_restarts_total{cluster=~\"$cluster\", namespace=~\"$namespace\", container=~\"^(coder|provisionerd)$\"}[1m]))", + "hide": false, + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Coder pod restarts", + "type": "timeseries" + }, + { + "datasource": { + "type": "stackdriver", + "uid": "${DS_GOOGLE_CLOUD MONITORING}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "#989898", + "mode": "fixed" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "fillOpacity": 80, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineWidth": 1, + "scaleDistribution": { + "type": "linear" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "blue", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 17 + }, + "id": 50, + "options": { + "barRadius": 0, + "barWidth": 0.97, + "fullHighlight": false, + "groupWidth": 0.7, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "orientation": "auto", + "showValue": "auto", + "stacking": "none", + "tooltip": { + "mode": "multi", + "sort": "none" + }, + "xTickLabelRotation": 0, + "xTickLabelSpacing": 200 + }, + "pluginVersion": "9.5.2", + "targets": [ + { + "datasource": { + "type": "stackdriver", + "uid": "${DS_GOOGLE_CLOUD MONITORING}" + }, + "queryType": "timeSeriesList", + "refId": "A", + "timeSeriesList": { + "alignmentPeriod": "+300s", + "crossSeriesReducer": "REDUCE_NONE", + "filters": [ + "resource.label.project_id", + "=", + "v2-loadtest", + "AND", + "resource.label.namespace_name", + "=", + "coder-big", + "AND", + "resource.label.container_name", + "=", + "coder", + "AND", + "resource.label.cluster_name", + "=", + "big", + "AND", + "resource.type", + "=", + "k8s_container", + "AND", + "resource.label.pod_name", + "!=~", + "coder-scaletest-.*", + "AND", + "resource.label.pod_name", + "=~", + "coder-.*", + "AND", + "metric.type", + "=", + "logging.googleapis.com/log_entry_count" + ], + "groupBys": [], + "perSeriesAligner": "ALIGN_SUM", + "preprocessor": "none", + "projectName": "v2-loadtest" + } + } + ], + "title": "Coder Logs Entries (All Levels)", + "type": "barchart" + }, + { + "datasource": { + "type": "googlecloud-logging-datasource", + "uid": "${DS_GOOGLE_CLOUD LOGGING :: V2-LOADTEST}" + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 17 + }, + "id": 51, + "options": { + "dedupStrategy": "none", + "enableLogDetails": true, + "prettifyLogMessage": false, + "showCommonLabels": false, + "showLabels": false, + "showTime": true, + "sortOrder": "Descending", + "wrapLogMessage": false + }, + "targets": [ + { + "datasource": { + "type": "googlecloud-logging-datasource", + "uid": "${DS_GOOGLE_CLOUD LOGGING :: V2-LOADTEST}" + }, + "projectId": "v2-loadtest", + "queryText": "resource.type=\"k8s_container\" AND\nresource.labels.cluster_name=\"big\" AND\nresource.labels.namespace_name=\"coder-big\" AND\nresource.labels.location=\"us-central1-a\" AND\nresource.labels.project_id=\"v2-loadtest\" AND\n(resource.labels.container_name=\"coder\" OR resource.labels.container_name=\"coder-provisionerd\") AND\njsonPayload.message!=\"\" AND\nseverity=\"ERROR\"", + "refId": "Error" + }, + { + "datasource": { + "type": "googlecloud-logging-datasource", + "uid": "${DS_GOOGLE_CLOUD LOGGING :: V2-LOADTEST}" + }, + "hide": false, + "projectId": "v2-loadtest", + "queryText": "resource.type=\"k8s_container\" AND\nresource.labels.cluster_name=\"big\" AND\nresource.labels.namespace_name=\"coder-big\" AND\nresource.labels.location=\"us-central1-a\" AND\nresource.labels.project_id=\"v2-loadtest\" AND\ntextPayload=~\"panic:.*\"", + "refId": "Panic" + } + ], + "title": "Coder Error Logs", + "type": "logs" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 25 + }, + "id": 29, + "panels": [], + "title": "Database", + "type": "row" + }, + { + "datasource": { + "type": "stackdriver", + "uid": "${DS_GOOGLE_CLOUD MONITORING}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "max": 1, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 26 + }, + "id": 52, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "stackdriver", + "uid": "${DS_GOOGLE_CLOUD MONITORING}" + }, + "queryType": "timeSeriesList", + "refId": "A", + "timeSeriesList": { + "alignmentPeriod": "cloud-monitoring-auto", + "crossSeriesReducer": "REDUCE_NONE", + "filters": [ + "resource.label.project_id", + "=", + "v2-loadtest", + "AND", + "metric.type", + "=", + "cloudsql.googleapis.com/database/cpu/utilization" + ], + "groupBys": ["resource.label.database_id"], + "perSeriesAligner": "ALIGN_NONE", + "preprocessor": "none", + "projectName": "v2-loadtest" + } + } + ], + "title": "DB CPU Util%", + "type": "timeseries" + }, + { + "datasource": { + "type": "stackdriver", + "uid": "${DS_GOOGLE_CLOUD MONITORING}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "max": 1, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 26 + }, + "id": 53, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "stackdriver", + "uid": "${DS_GOOGLE_CLOUD MONITORING}" + }, + "queryType": "timeSeriesList", + "refId": "A", + "timeSeriesList": { + "alignmentPeriod": "cloud-monitoring-auto", + "crossSeriesReducer": "REDUCE_NONE", + "filters": [ + "resource.label.project_id", + "=", + "v2-loadtest", + "AND", + "metric.type", + "=", + "cloudsql.googleapis.com/database/memory/utilization" + ], + "groupBys": [], + "perSeriesAligner": "ALIGN_NONE", + "preprocessor": "none", + "projectName": "v2-loadtest" + } + } + ], + "title": "DB Mem Util%", + "type": "timeseries" + }, + { + "datasource": { + "type": "stackdriver", + "uid": "${DS_GOOGLE_CLOUD MONITORING}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 34 + }, + "id": 54, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "stackdriver", + "uid": "${DS_GOOGLE_CLOUD MONITORING}" + }, + "queryType": "timeSeriesList", + "refId": "A", + "timeSeriesList": { + "alignmentPeriod": "+60s", + "crossSeriesReducer": "REDUCE_NONE", + "filters": [ + "resource.label.project_id", + "=", + "v2-loadtest", + "AND", + "metric.type", + "=", + "cloudsql.googleapis.com/database/disk/read_ops_count" + ], + "groupBys": [], + "perSeriesAligner": "ALIGN_DELTA", + "preprocessor": "none", + "projectName": "v2-loadtest" + } + } + ], + "title": "DB Disk Read I/O", + "type": "timeseries" + }, + { + "datasource": { + "type": "stackdriver", + "uid": "${DS_GOOGLE_CLOUD MONITORING}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 34 + }, + "id": 55, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "stackdriver", + "uid": "${DS_GOOGLE_CLOUD MONITORING}" + }, + "queryType": "timeSeriesList", + "refId": "A", + "timeSeriesList": { + "alignmentPeriod": "cloud-monitoring-auto", + "crossSeriesReducer": "REDUCE_NONE", + "filters": [ + "resource.label.project_id", + "=", + "v2-loadtest", + "AND", + "metric.type", + "=", + "cloudsql.googleapis.com/database/disk/write_ops_count" + ], + "groupBys": [], + "perSeriesAligner": "ALIGN_NONE", + "preprocessor": "rate", + "projectName": "v2-loadtest" + } + } + ], + "title": "DB Disk Write I/O", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "LOGARITHMIC Y AXIS", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "bars", + "fillOpacity": 100, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "log": 2, + "type": "log" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "normal" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 16, + "w": 12, + "x": 0, + "y": 42 + }, + "id": 36, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(rate(pg_stat_database_tup_inserted{cluster=~\"$cluster\", datname=\"${cluster}-coder\"}[$__rate_interval]))", + "hide": false, + "legendFormat": "INSERT", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(rate(pg_stat_database_tup_updated{cluster=~\"$cluster\", datname=\"${cluster}-coder\"}[$__rate_interval]))", + "hide": false, + "legendFormat": "UPDATE", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(rate(pg_stat_database_tup_deleted{cluster=~\"$cluster\", datname=\"${cluster}-coder\"}[$__rate_interval]))", + "hide": false, + "legendFormat": "DELETE", + "range": true, + "refId": "C" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(rate(pg_stat_database_tup_returned{cluster=~\"$cluster\", datname=\"${cluster}-coder\"}[$__rate_interval]))", + "hide": false, + "legendFormat": "RETURN", + "range": true, + "refId": "D" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(rate(pg_stat_database_tup_fetched{cluster=~\"$cluster\", datname=\"${cluster}-coder\"}[$__rate_interval]))", + "hide": false, + "legendFormat": "FETCH", + "range": true, + "refId": "E" + } + ], + "title": "DB insert/update/delete/return", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "bars", + "fillOpacity": 100, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "normal" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 42 + }, + "id": 39, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "pg_stat_activity_count{datname=~\"${cluster}-coder\", cluster=~\"${cluster}\", state=\"active\"} !=0", + "hide": false, + "legendFormat": "active", + "range": true, + "refId": "C" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "pg_stat_activity_count{datname=~\"${cluster}-coder\", cluster=~\"${cluster}\", state=\"idle\"} !=0", + "hide": false, + "legendFormat": "idle", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "pg_stat_activity_count{datname=~\"${cluster}-coder\", cluster=~\"${cluster}\", state=\"idle in transaction\"} != 0", + "hide": false, + "legendFormat": "idle_tx", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "pg_stat_activity_count{datname=~\"${cluster}-coder\", cluster=~\"${cluster}\", state=\"disabled\"} != 0", + "hide": false, + "legendFormat": "disabled", + "range": true, + "refId": "D" + } + ], + "title": "DB conns", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 50 + }, + "id": 37, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "sum(rate(pg_stat_database_xact_commit{cluster=~\"$cluster\", datname=\"${cluster}-coder\"}[$__rate_interval]))", + "hide": false, + "legendFormat": "commit", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "sum(rate(pg_stat_database_xact_rollback{cluster=~\"$cluster\", datname=\"${cluster}-coder\"}[$__rate_interval]))", + "hide": false, + "legendFormat": "rollback", + "range": true, + "refId": "A" + } + ], + "title": "DB TX/s", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "custom": { + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "gridPos": { + "h": 26, + "w": 12, + "x": 0, + "y": 58 + }, + "id": 30, + "options": { + "calculate": false, + "cellGap": 1, + "cellValues": { + "unit": "s" + }, + "color": { + "exponent": 0.5, + "fill": "dark-orange", + "min": 0, + "mode": "scheme", + "reverse": false, + "scale": "exponential", + "scheme": "Viridis", + "steps": 64 + }, + "exemplars": { + "color": "rgba(255,0,255,0.7)" + }, + "filterValues": { + "le": 1e-9 + }, + "legend": { + "show": true + }, + "rowsFrame": { + "layout": "auto" + }, + "tooltip": { + "mode": "single", + "showColorScale": false, + "yHistogram": false + }, + "yAxis": { + "axisPlacement": "left", + "reverse": false + } + }, + "pluginVersion": "11.1.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "histogram_quantile(0.95, sum by(le, query) (rate(coderd_db_query_latencies_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$pod\"}[$__rate_interval])))", + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "sqlQuerier P95 execution timing", + "type": "heatmap" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "custom": { + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "gridPos": { + "h": 26, + "w": 12, + "x": 12, + "y": 58 + }, + "id": 31, + "options": { + "calculate": false, + "cellGap": 1, + "cellValues": { + "unit": "reqps" + }, + "color": { + "exponent": 0.5, + "fill": "dark-orange", + "min": 0, + "mode": "scheme", + "reverse": false, + "scale": "exponential", + "scheme": "Viridis", + "steps": 64 + }, + "exemplars": { + "color": "rgba(255,0,255,0.7)" + }, + "filterValues": { + "le": 1e-9 + }, + "legend": { + "show": true + }, + "rowsFrame": { + "layout": "auto" + }, + "tooltip": { + "mode": "single", + "showColorScale": false, + "yHistogram": false + }, + "yAxis": { + "axisPlacement": "left", + "reverse": false + } + }, + "pluginVersion": "11.1.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum by(le, query) (rate(coderd_db_query_latencies_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$pod\"}[$__rate_interval]))", + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "sqlQuerier execution count", + "type": "heatmap" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 84 + }, + "id": 16, + "panels": [], + "title": "HTTP Requests", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "reqps" + }, + "overrides": [] + }, + "gridPos": { + "h": 11, + "w": 12, + "x": 0, + "y": 85 + }, + "id": 45, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "exemplar": false, + "expr": "sum by(pod) (rate(coderd_api_requests_processed_total{cluster=\"$cluster\", namespace=~\"$namespace\", pod=~\"$pod\"}[$__rate_interval]))", + "instant": true, + "key": "Q-2eb2f8ac-845d-462d-9bb0-b98334fbfd4a-0", + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "API Requests by pod", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 11, + "w": 12, + "x": 12, + "y": 85 + }, + "id": 44, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum(rate(coderd_api_requests_processed_total{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=~\"$pod\", code=~\"5..\"}[$__rate_interval]))", + "instant": true, + "key": "Q-2eb2f8ac-845d-462d-9bb0-b98334fbfd4a-0", + "legendFormat": "5xx", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(rate(coderd_api_requests_processed_total{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=~\"$pod\", code=~\"4..\"}[$__rate_interval]))", + "instant": true, + "key": "Q-fe3b7389-28e7-4b2c-90ef-3b1490f99528-1", + "legendFormat": "4xx", + "range": true, + "refId": "B" + } + ], + "title": "API Error Rate", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "custom": { + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 24, + "x": 0, + "y": 96 + }, + "id": 4, + "options": { + "calculate": false, + "cellGap": 1, + "color": { + "exponent": 0.5, + "fill": "dark-orange", + "min": 0, + "mode": "scheme", + "reverse": false, + "scale": "exponential", + "scheme": "Viridis", + "steps": 64 + }, + "exemplars": { + "color": "rgba(255,0,255,0.7)" + }, + "filterValues": { + "le": 1e-9 + }, + "legend": { + "show": true + }, + "rowsFrame": { + "layout": "auto" + }, + "tooltip": { + "show": true, + "yHistogram": false + }, + "yAxis": { + "axisPlacement": "left", + "reverse": false + } + }, + "pluginVersion": "9.5.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum by (code,method) (rate(coderd_api_requests_processed_total{cluster=~\"$cluster\",namespace=~\"$namespace\",pod=~\"$pod\",container=\"coder\",code!=\"0\"}[$__rate_interval]))", + "legendFormat": "{{method}} {{code}}", + "range": true, + "refId": "A" + } + ], + "title": "API requests/sec by response, method", + "type": "heatmap" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "custom": { + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "gridPos": { + "h": 18, + "w": 12, + "x": 0, + "y": 106 + }, + "id": 33, + "options": { + "calculate": false, + "cellGap": 1, + "cellValues": { + "unit": "s" + }, + "color": { + "exponent": 0.5, + "fill": "dark-orange", + "mode": "scheme", + "reverse": false, + "scale": "exponential", + "scheme": "Viridis", + "steps": 64 + }, + "exemplars": { + "color": "rgba(255,0,255,0.7)" + }, + "filterValues": { + "le": 1e-9 + }, + "legend": { + "show": true + }, + "rowsFrame": { + "layout": "auto" + }, + "tooltip": { + "show": true, + "yHistogram": false + }, + "yAxis": { + "axisPlacement": "left", + "reverse": false + } + }, + "pluginVersion": "9.5.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "histogram_quantile(0.95, sum by(le, path) (rate(coderd_api_request_latencies_seconds_bucket{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=~\"$pod\", path=~\"^/api/v2/.*\"}[$__rate_interval])))", + "interval": "", + "legendFormat": "{{path}}", + "range": true, + "refId": "A" + } + ], + "title": "API Request Latency P95", + "type": "heatmap" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "custom": { + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "gridPos": { + "h": 18, + "w": 12, + "x": 12, + "y": 106 + }, + "id": 34, + "options": { + "calculate": false, + "cellGap": 1, + "color": { + "exponent": 0.5, + "fill": "dark-orange", + "mode": "scheme", + "reverse": false, + "scale": "exponential", + "scheme": "Viridis", + "steps": 64 + }, + "exemplars": { + "color": "rgba(255,0,255,0.7)" + }, + "filterValues": { + "le": 1e-9 + }, + "legend": { + "show": true + }, + "rowsFrame": { + "layout": "auto" + }, + "tooltip": { + "show": true, + "yHistogram": false + }, + "yAxis": { + "axisPlacement": "left", + "reverse": false + } + }, + "pluginVersion": "9.5.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "sum by(method, path) (rate(coderd_api_request_latencies_seconds_count{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=~\"$pod\", path=~\"^/api/v2/.*\"}[$__rate_interval]))", + "interval": "", + "legendFormat": "{{method}} {{path}}", + "range": true, + "refId": "A" + } + ], + "title": "API Requests", + "type": "heatmap" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 124 + }, + "id": 40, + "panels": [], + "title": "Workspace Resources", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 1, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "limit" + }, + "properties": [ + { + "id": "custom.drawStyle", + "value": "line" + }, + { + "id": "custom.lineStyle", + "value": { + "dash": [10, 10], + "fill": "dash" + } + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 125 + }, + "id": 41, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "max(kube_pod_container_resource_limits{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=~\"coder-scaletest-.*-scaletest-.*\", pod!=\"coder-scaletest-runner-scaletest-runner\", resource=\"cpu\"})", + "legendFormat": "limit", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "avg(rate(container_cpu_usage_seconds_total{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=~\"coder-scaletest-.*-scaletest-.*\", pod!=\"coder-scaletest-runner-scaletest-runner\", container=\"dev\"}[$__rate_interval]))", + "hide": false, + "legendFormat": "__auto", + "range": true, + "refId": "B" + } + ], + "title": "Scaletest Workspace CPU Usage (Avg)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": true, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 1, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": 60000, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + }, + "unit": "binBps" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "limit" + }, + "properties": [ + { + "id": "custom.drawStyle", + "value": "line" + }, + { + "id": "custom.lineStyle", + "value": { + "dash": [10, 10], + "fill": "dash" + } + } + ] + } + ] + }, + "gridPos": { + "h": 16, + "w": 12, + "x": 12, + "y": 125 + }, + "id": 43, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(rate(container_network_receive_bytes_total{cluster=~\"${cluster}\", namespace=~\"${namespace}\", pod=~\"coder-scaletest-.*-scaletest-.*\", pod!=\"coder-scaletest-runner-scaletest-runner\"}[$__rate_interval]))", + "format": "time_series", + "hide": false, + "legendFormat": "rx", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(rate(container_network_transmit_bytes_total{cluster=~\"${cluster}\", namespace=~\"${namespace}\", pod=~\"coder-scaletest-.*-scaletest-.*\", pod!=\"coder-scaletest-runner-scaletest-runner\"}[$__rate_interval])) * -1", + "hide": false, + "legendFormat": "tx {{pod}}", + "range": true, + "refId": "A" + } + ], + "title": "Scaletest Workspace Network Usage (Sum)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 1, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + }, + "unit": "bytes" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "limit" + }, + "properties": [ + { + "id": "custom.drawStyle", + "value": "line" + }, + { + "id": "custom.lineStyle", + "value": { + "dash": [10, 10], + "fill": "dash" + } + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 133 + }, + "id": 42, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "max(kube_pod_container_resource_limits{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=~\"coder-scaletest-.*-scaletest-.*\", pod!=\"coder-scaletest-runner-scaletest-runner\", resource=\"memory\"})", + "legendFormat": "limit", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "avg(container_memory_usage_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=~\"coder-scaletest-.*-scaletest-.*\", pod!=\"coder-scaletest-runner-scaletest-runner\", container!=\"\"})", + "hide": false, + "legendFormat": "__auto", + "range": true, + "refId": "B" + } + ], + "title": "Scaletest Workspace Memory Usage (Avg)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": true, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 1, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": 60000, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + }, + "unit": "none" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "limit" + }, + "properties": [ + { + "id": "custom.drawStyle", + "value": "line" + }, + { + "id": "custom.lineStyle", + "value": { + "dash": [10, 10], + "fill": "dash" + } + } + ] + } + ] + }, + "gridPos": { + "h": 16, + "w": 12, + "x": 12, + "y": 141 + }, + "id": 56, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(rate(container_network_receive_errors_total{cluster=~\"${cluster}\", namespace=~\"${namespace}\", pod=~\"coder-scaletest-.*-scaletest-.*\", pod!=\"coder-scaletest-runner-scaletest-runner\"}[$__rate_interval]))", + "format": "time_series", + "hide": false, + "legendFormat": "rx errs {{pod}}", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(rate(container_network_transmit_errors_total{cluster=~\"${cluster}\", namespace=~\"${namespace}\", pod=~\"coder-scaletest-.*-scaletest-.*\", pod!=\"coder-scaletest-runner-scaletest-runner\"}[$__rate_interval])) * -1", + "hide": false, + "legendFormat": "tx errs {{pod}}", + "range": true, + "refId": "A" + } + ], + "title": "Scaletest Workspace Network RX/TX errs (Sum)", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 157 + }, + "id": 18, + "panels": [], + "title": "Workspace Agents", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": true, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": 3600000, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "bytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 18, + "w": 12, + "x": 0, + "y": 158 + }, + "id": 20, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "9.5.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "sum(rate(coderd_agentstats_rx_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=~\"$pod\"}[$__rate_interval]))", + "legendFormat": "rx", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "sum(rate(coderd_agentstats_tx_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=~\"$pod\"}[$__rate_interval])) * -1", + "hide": false, + "legendFormat": "tx", + "range": true, + "refId": "B" + } + ], + "title": "Agent Connection RX/TX", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 18, + "gradientMode": "hue", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 3, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 18, + "w": 12, + "x": 12, + "y": 158 + }, + "id": 38, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "9.5.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "quantile(0.5, coderd_agents_connection_latencies_seconds{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=~\"$pod\"})", + "legendFormat": "p50", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "quantile(0.95, coderd_agents_connection_latencies_seconds{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=~\"$pod\"})", + "hide": false, + "legendFormat": "p95", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "quantile(0.99, coderd_agents_connection_latencies_seconds{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=~\"$pod\"})", + "hide": false, + "legendFormat": "p99", + "range": true, + "refId": "C" + } + ], + "title": "Agent Connection Latency P50/95/99", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 176 + }, + "id": 3, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "sum by(pod) (coderd_api_concurrent_websockets{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=~\"$pod\", container=\"coder\"})", + "format": "time_series", + "interval": "", + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Websocket Connections", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 176 + }, + "id": 19, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum by (pod) (coderd_agents_connections{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=~\"$pod\"})", + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Agent Connections", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 185 + }, + "id": 14, + "panels": [], + "title": "Workspace Traffic", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": true, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 22, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "binBps" + }, + "overrides": [] + }, + "gridPos": { + "h": 16, + "w": 12, + "x": 0, + "y": 186 + }, + "id": 11, + "options": { + "legend": { + "calcs": [], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "9.5.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "sum by(pod) (rate(coderd_scaletest_bytes_written_total{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval])) * -1", + "legendFormat": "tx inside container", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "sum by(pod) (rate(coderd_scaletest_bytes_read_total{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval]))", + "hide": false, + "legendFormat": "rx inside container", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "sum by(pod) (rate(container_network_receive_bytes_total{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=\"coder-scaletest-workspace-traffic\"}[$__rate_interval])) * 1", + "hide": false, + "legendFormat": "rx outside container", + "range": true, + "refId": "C" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "sum by(pod) (rate(container_network_transmit_bytes_total{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=\"coder-scaletest-workspace-traffic\"}[$__rate_interval])) * -1", + "hide": false, + "legendFormat": "tx outside container", + "range": true, + "refId": "D" + } + ], + "title": "Workspace Traffic bytes TX/RX", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 3, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 186 + }, + "id": 12, + "options": { + "legend": { + "calcs": [], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "9.5.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "histogram_quantile(0.95, sum by(le, pod) (rate(coderd_scaletest_read_latency_seconds_bucket{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval])))", + "hide": false, + "legendFormat": "__auto", + "range": true, + "refId": "B" + } + ], + "title": "Workspace Traffic read latency P95", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 194 + }, + "id": 32, + "options": { + "legend": { + "calcs": [], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "9.5.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "histogram_quantile(0.95, sum by(le, pod) (rate(coderd_scaletest_write_latency_seconds_bucket{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval])))", + "hide": false, + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Workspace Traffic write latency P95", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 202 + }, + "id": 13, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "9.5.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "sum by(pod) (rate(coderd_scaletest_read_errors_total{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval]))", + "hide": false, + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Workspace Traffic Read errors", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 202 + }, + "id": 28, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "9.5.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "sum by(pod) (rate(coderd_scaletest_write_errors_total{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval]))", + "hide": false, + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Workspace Traffic Write errors", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "requests" + }, + "properties": [ + { + "id": "custom.spanNulls", + "value": true + }, + { + "id": "custom.lineStyle", + "value": { + "dash": [10, 10], + "fill": "dash" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "limit" + }, + "properties": [ + { + "id": "custom.spanNulls", + "value": true + }, + { + "id": "custom.lineStyle", + "value": { + "dash": [10, 10], + "fill": "dash" + } + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 210 + }, + "id": 22, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum by(pod) (rate(container_cpu_usage_seconds_total{cluster=~\"$cluster\", namespace=~\"$namespace\",pod=\"coder-scaletest-runner-scaletest-runner\", container=\"dev\"}[$__rate_interval]))", + "hide": false, + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Traffic Generation CPU usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + }, + "unit": "bytes" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "requests" + }, + "properties": [ + { + "id": "custom.spanNulls", + "value": true + }, + { + "id": "custom.lineStyle", + "value": { + "dash": [10, 10], + "fill": "dash" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "limit" + }, + "properties": [ + { + "id": "custom.spanNulls", + "value": true + }, + { + "id": "custom.lineStyle", + "value": { + "dash": [10, 10], + "fill": "dash" + } + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 210 + }, + "id": 23, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum by(pod) (container_memory_working_set_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\",pod=\"coder-scaletest-runner-scaletest-runner\",container=\"dev\"})", + "hide": false, + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Traffic Generation Memory usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "axisSoftMin": 0, + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + }, + "unit": "none" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "requests" + }, + "properties": [ + { + "id": "custom.spanNulls", + "value": true + }, + { + "id": "custom.lineStyle", + "value": { + "dash": [10, 10], + "fill": "dash" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "limit" + }, + "properties": [ + { + "id": "custom.spanNulls", + "value": true + }, + { + "id": "custom.lineStyle", + "value": { + "dash": [10, 10], + "fill": "dash" + } + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 210 + }, + "id": 26, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum by(pod) (increase(kube_pod_container_status_restarts_total{cluster=~\"$cluster\", namespace=~\"$namespace\",pod=\"coder-scaletest-runner-scaletest-runner\"}[$__rate_interval]))", + "hide": false, + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Traffic generation pod restarts", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 218 + }, + "id": 46, + "panels": [], + "title": "Scaletest Dashboard Actions", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "log": 2, + "type": "log" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 19, + "w": 12, + "x": 0, + "y": 219 + }, + "id": 47, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "histogram_quantile(0.95, sum by(le, action) (rate(coderd_scaletest_dashboard_duration_seconds_bucket{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=~\"$pod\"}[$__rate_interval])))", + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Dashboard Actions Duration P95", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "bars", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "normal" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 19, + "w": 12, + "x": 12, + "y": 219 + }, + "id": 49, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum by(le, action) (rate(coderd_scaletest_dashboard_errors_total{cluster=~\"$cluster\", namespace=~\"$namespace\", pod=~\"$pod\"}[$__rate_interval]))", + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Dashboard Actions Errors", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 238 + }, + "id": 17, + "panels": [], + "title": "Internals", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 31, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 239 + }, + "id": 5, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "histogram_quantile(0.5, sum by(le) (rate(coderd_authz_authorize_duration_seconds_bucket{cluster=~\"$cluster\",namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])))", + "interval": "", + "legendFormat": "p50", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "histogram_quantile(0.9, sum by(le) (rate(coderd_authz_authorize_duration_seconds_bucket{cluster=~\"$cluster\",namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])))", + "hide": false, + "interval": "", + "legendFormat": "p90", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "histogram_quantile(0.95, sum by(le) (rate(coderd_authz_authorize_duration_seconds_bucket{cluster=~\"$cluster\",namespace=~\"$namespace\",pod=~\"$pod\"}[$__rate_interval])))", + "hide": false, + "interval": "", + "legendFormat": "p95", + "range": true, + "refId": "C" + } + ], + "title": "AuthZ Duration", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 31, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 239 + }, + "id": 6, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "histogram_quantile(0.5, sum by(le, pod) (rate(coderd_provisionerd_job_timings_seconds_bucket{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval])))", + "interval": "", + "legendFormat": "p50-{{pod}}", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "histogram_quantile(0.9, sum by(le, pod) (rate(coderd_provisionerd_job_timings_seconds_bucket{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval])))", + "hide": false, + "interval": "", + "legendFormat": "p90-{{pod}}", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "histogram_quantile(0.95, sum by(le, pod) (rate(coderd_provisionerd_job_timings_seconds_bucket{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval])))", + "hide": false, + "interval": "", + "legendFormat": "p95-{{pod}}", + "range": true, + "refId": "C" + } + ], + "title": "Provisioner Job Timings", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "bars", + "fillOpacity": 69, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "normal" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 246 + }, + "id": 8, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "sum by(status, pod) (coderd_workspace_builds_total{cluster=~\"$cluster\", namespace=~\"$namespace\", workspace_transition=\"START\"})", + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Total Workspace Builds", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "bars", + "fillOpacity": 69, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "normal" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "daemons" + }, + "properties": [ + { + "id": "custom.drawStyle", + "value": "line" + }, + { + "id": "custom.fillOpacity", + "value": 0 + }, + { + "id": "color", + "value": { + "mode": "continuous-BlYlRd" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "external_daemons" + }, + "properties": [ + { + "id": "custom.drawStyle", + "value": "line" + }, + { + "id": "custom.fillOpacity", + "value": 0 + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 246 + }, + "id": 35, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum by(status, container) (coderd_provisionerd_jobs_current{cluster=~\"$cluster\", namespace=~\"$namespace\", container=~\"^(coder|provisionerd)$\"})", + "legendFormat": "__auto", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum by(status, container) (coderd_provisionerd_num_daemons{cluster=~\"$cluster\", namespace=~\"$namespace\", container=~\"^(coder|provisionerd)$\"})", + "hide": false, + "legendFormat": "builtin_daemons", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(kube_pod_container_status_running {cluster=~\"$cluster\", namespace=~\"coder-big\", pod=~\"coder-provisioner-.*\"})", + "hide": false, + "legendFormat": "external_daemons", + "range": true, + "refId": "C" + } + ], + "title": "Concurrent Provisioner Jobs", + "type": "timeseries" + } + ], + "refresh": false, + "schemaVersion": 39, + "tags": [], + "templating": { + "list": [ + { + "allValue": ".*", + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "definition": "label_values(coderd_api_concurrent_requests,cluster)", + "hide": 0, + "includeAll": false, + "label": "cluster", + "multi": false, + "name": "cluster", + "options": [], + "query": { + "query": "label_values(coderd_api_concurrent_requests,cluster)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 1, + "type": "query" + }, + { + "allValue": ".*", + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "definition": "label_values(coderd_api_concurrent_requests,namespace)", + "hide": 0, + "includeAll": false, + "label": "namespace", + "multi": false, + "name": "namespace", + "options": [], + "query": { + "query": "label_values(coderd_api_concurrent_requests,namespace)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "type": "query" + }, + { + "allValue": ".*", + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "definition": "label_values(coderd_api_concurrent_requests,pod)", + "hide": 0, + "includeAll": true, + "label": "pod", + "multi": false, + "name": "pod", + "options": [], + "query": { + "query": "label_values(coderd_api_concurrent_requests,pod)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "type": "query" + } + ] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "CoderV2 Loadtest Dashboard", + "uid": "qLVSTR-Vz", + "version": 254, + "weekStart": "" } diff --git a/scripts/apidocgen/package.json b/scripts/apidocgen/package.json index 1e1854f293..30b3679e64 100644 --- a/scripts/apidocgen/package.json +++ b/scripts/apidocgen/package.json @@ -1,9 +1,9 @@ { - "dependencies": { - "widdershins": "^4.0.1" - }, - "resolutions": { - "semver": "7.5.3", - "jsonpointer": "5.0.1" - } + "dependencies": { + "widdershins": "^4.0.1" + }, + "resolutions": { + "semver": "7.5.3", + "jsonpointer": "5.0.1" + } } diff --git a/scripts/apitypings/main.go b/scripts/apitypings/main.go index 98bfbc47ea..be6b6405b3 100644 --- a/scripts/apitypings/main.go +++ b/scripts/apitypings/main.go @@ -39,7 +39,7 @@ var ( // CLI option types: "github.com/coder/serpent", } - indent = " " + indent = "\t" ) func main() { diff --git a/scripts/apitypings/testdata/genericmap/genericmap.ts b/scripts/apitypings/testdata/genericmap/genericmap.ts index 417dd7e2e8..6b3a40a41d 100644 --- a/scripts/apitypings/testdata/genericmap/genericmap.ts +++ b/scripts/apitypings/testdata/genericmap/genericmap.ts @@ -1,17 +1,17 @@ // From codersdk/genericmap.go export interface Buzz { - readonly foo: Foo - readonly bazz: string + readonly foo: Foo + readonly bazz: string } // From codersdk/genericmap.go export interface Foo { - readonly bar: string + readonly bar: string } // From codersdk/genericmap.go export interface FooBuzz { - readonly something: (readonly R[]) + readonly something: (readonly R[]) } // From codersdk/genericmap.go diff --git a/scripts/apitypings/testdata/generics/generics.ts b/scripts/apitypings/testdata/generics/generics.ts index 2a11bb5cd3..8dcf96f4b5 100644 --- a/scripts/apitypings/testdata/generics/generics.ts +++ b/scripts/apitypings/testdata/generics/generics.ts @@ -1,35 +1,35 @@ // From codersdk/generics.go export interface Complex { - readonly dynamic: Fields - readonly order: FieldsDiffOrder - readonly comparable: C - readonly single: S - readonly static: Static + readonly dynamic: Fields + readonly order: FieldsDiffOrder + readonly comparable: C + readonly single: S + readonly static: Static } // From codersdk/generics.go export interface Dynamic { - readonly dynamic: Fields - readonly comparable: boolean + readonly dynamic: Fields + readonly comparable: boolean } // From codersdk/generics.go export interface Fields { - readonly comparable: C - readonly any: A - readonly custom: T - readonly again: T - readonly single_constraint: S + readonly comparable: C + readonly any: A + readonly custom: T + readonly again: T + readonly single_constraint: S } // From codersdk/generics.go export interface FieldsDiffOrder { - readonly Fields: Fields + readonly Fields: Fields } // From codersdk/generics.go export interface Static { - readonly static: Fields + readonly static: Fields } // From codersdk/generics.go diff --git a/scripts/apitypings/testdata/genericslice/genericslice.ts b/scripts/apitypings/testdata/genericslice/genericslice.ts index fc88c04a87..5abd9eebbc 100644 --- a/scripts/apitypings/testdata/genericslice/genericslice.ts +++ b/scripts/apitypings/testdata/genericslice/genericslice.ts @@ -1,10 +1,10 @@ // From codersdk/genericslice.go export interface Bar { - readonly Bar: string + readonly Bar: string } // From codersdk/genericslice.go export interface Foo { - readonly Slice: (readonly R[]) - readonly TwoD: (readonly (readonly R[])[]) + readonly Slice: (readonly R[]) + readonly TwoD: (readonly (readonly R[])[]) } \ No newline at end of file diff --git a/scripts/examplegen/main.go b/scripts/examplegen/main.go index 742d27b05a..97ff02db82 100644 --- a/scripts/examplegen/main.go +++ b/scripts/examplegen/main.go @@ -98,7 +98,7 @@ func run(lint bool) error { } enc := json.NewEncoder(w) - enc.SetIndent("", " ") + enc.SetIndent("", "\t") return enc.Encode(examples) } diff --git a/site/biome.json b/site/biome.json index 50e0e759ee..9ec2052b17 100644 --- a/site/biome.json +++ b/site/biome.json @@ -1,45 +1,41 @@ { - "files": { - "ignore": ["**/*Generated.ts"] - }, - "formatter": { - "indentStyle": "space", - "indentWidth": 2 - }, - "linter": { - "rules": { - "a11y": { - "noSvgWithoutTitle": { "level": "off" }, - "useButtonType": { "level": "off" } - }, - "style": { - "noNonNullAssertion": { "level": "off" }, - "noParameterAssign": { "level": "off" }, - "useDefaultParameterLast": { "level": "off" }, - "useSelfClosingElements": { "level": "off" } - }, - "suspicious": { - "noArrayIndexKey": { "level": "off" }, - "noThenProperty": { "level": "off" } - }, - "nursery": { - "noRestrictedImports": { - "level": "error", - "options": { - "paths": { - "@mui/material": "Use @mui/material/ instead. See: https://material-ui.com/guides/minimizing-bundle-size/.", - "@mui/icons-material": "Use @mui/icons-material/ instead. See: https://material-ui.com/guides/minimizing-bundle-size/.", - "@mui/material/Avatar": "Use components/Avatar/Avatar instead.", - "@mui/material/Alert": "Use components/Alert/Alert instead.", - "@mui/material/Popover": "Use components/Popover/Popover instead.", - "@mui/material/Typography": "Use native HTML elements instead. Eg: ,

,

, etc.", - "@mui/material/Box": "Use a
instead.", - "@mui/material/styles": "Import from @emotion/react instead.", - "lodash": "Use lodash/ instead." - } - } - } - } - } - } + "files": { + "ignore": ["**/*Generated.ts"] + }, + "linter": { + "rules": { + "a11y": { + "noSvgWithoutTitle": { "level": "off" }, + "useButtonType": { "level": "off" } + }, + "style": { + "noNonNullAssertion": { "level": "off" }, + "noParameterAssign": { "level": "off" }, + "useDefaultParameterLast": { "level": "off" }, + "useSelfClosingElements": { "level": "off" } + }, + "suspicious": { + "noArrayIndexKey": { "level": "off" }, + "noThenProperty": { "level": "off" } + }, + "nursery": { + "noRestrictedImports": { + "level": "error", + "options": { + "paths": { + "@mui/material": "Use @mui/material/ instead. See: https://material-ui.com/guides/minimizing-bundle-size/.", + "@mui/icons-material": "Use @mui/icons-material/ instead. See: https://material-ui.com/guides/minimizing-bundle-size/.", + "@mui/material/Avatar": "Use components/Avatar/Avatar instead.", + "@mui/material/Alert": "Use components/Alert/Alert instead.", + "@mui/material/Popover": "Use components/Popover/Popover instead.", + "@mui/material/Typography": "Use native HTML elements instead. Eg: ,

,

, etc.", + "@mui/material/Box": "Use a
instead.", + "@mui/material/styles": "Import from @emotion/react instead.", + "lodash": "Use lodash/ instead." + } + } + } + } + } + } } diff --git a/site/e2e/api.ts b/site/e2e/api.ts index 7712c52858..3f274a3c01 100644 --- a/site/e2e/api.ts +++ b/site/e2e/api.ts @@ -9,174 +9,174 @@ import { findSessionToken, randomName } from "./helpers"; let currentOrgId: string; export const setupApiCalls = async (page: Page) => { - try { - const token = await findSessionToken(page); - API.setSessionToken(token); - } catch { - // If this fails, we have an unauthenticated client. - } + try { + const token = await findSessionToken(page); + API.setSessionToken(token); + } catch { + // If this fails, we have an unauthenticated client. + } - API.setHost(`http://127.0.0.1:${coderPort}`); + API.setHost(`http://127.0.0.1:${coderPort}`); }; export const getCurrentOrgId = async (): Promise => { - if (currentOrgId) { - return currentOrgId; - } - const currentUser = await API.getAuthenticatedUser(); - currentOrgId = currentUser.organization_ids[0]; - return currentOrgId; + if (currentOrgId) { + return currentOrgId; + } + const currentUser = await API.getAuthenticatedUser(); + currentOrgId = currentUser.organization_ids[0]; + return currentOrgId; }; export const createUser = async (orgId: string) => { - const name = randomName(); - const user = await API.createUser({ - email: `${name}@coder.com`, - username: name, - name: name, - password: "s3cure&password!", - login_type: "password", - disable_login: false, - organization_id: orgId, - }); - return user; + const name = randomName(); + const user = await API.createUser({ + email: `${name}@coder.com`, + username: name, + name: name, + password: "s3cure&password!", + login_type: "password", + disable_login: false, + organization_id: orgId, + }); + return user; }; export const createGroup = async (orgId: string) => { - const name = randomName(); - const group = await API.createGroup(orgId, { - name, - display_name: `Display ${name}`, - avatar_url: "/emojis/1f60d.png", - quota_allowance: 0, - }); - return group; + const name = randomName(); + const group = await API.createGroup(orgId, { + name, + display_name: `Display ${name}`, + avatar_url: "/emojis/1f60d.png", + quota_allowance: 0, + }); + return group; }; export const createOrganization = async () => { - const name = randomName(); - const org = await API.createOrganization({ - name, - display_name: `Org ${name}`, - description: `Org description ${name}`, - icon: "/emojis/1f957.png", - }); - return org; + const name = randomName(); + const org = await API.createOrganization({ + name, + display_name: `Org ${name}`, + description: `Org description ${name}`, + icon: "/emojis/1f957.png", + }); + return org; }; export async function verifyConfigFlagBoolean( - page: Page, - config: DeploymentConfig, - flag: string, + page: Page, + config: DeploymentConfig, + flag: string, ) { - const opt = findConfigOption(config, flag); - const type = opt.value ? "option-enabled" : "option-disabled"; - const value = opt.value ? "Enabled" : "Disabled"; + const opt = findConfigOption(config, flag); + const type = opt.value ? "option-enabled" : "option-disabled"; + const value = opt.value ? "Enabled" : "Disabled"; - const configOption = page.locator( - `div.options-table .option-${flag} .${type}`, - ); - await expect(configOption).toHaveText(value); + const configOption = page.locator( + `div.options-table .option-${flag} .${type}`, + ); + await expect(configOption).toHaveText(value); } export async function verifyConfigFlagNumber( - page: Page, - config: DeploymentConfig, - flag: string, + page: Page, + config: DeploymentConfig, + flag: string, ) { - const opt = findConfigOption(config, flag); - const configOption = page.locator( - `div.options-table .option-${flag} .option-value-number`, - ); - await expect(configOption).toHaveText(String(opt.value)); + const opt = findConfigOption(config, flag); + const configOption = page.locator( + `div.options-table .option-${flag} .option-value-number`, + ); + await expect(configOption).toHaveText(String(opt.value)); } export async function verifyConfigFlagString( - page: Page, - config: DeploymentConfig, - flag: string, + page: Page, + config: DeploymentConfig, + flag: string, ) { - const opt = findConfigOption(config, flag); + const opt = findConfigOption(config, flag); - const configOption = page.locator( - `div.options-table .option-${flag} .option-value-string`, - ); - await expect(configOption).toHaveText(opt.value); + const configOption = page.locator( + `div.options-table .option-${flag} .option-value-string`, + ); + await expect(configOption).toHaveText(opt.value); } export async function verifyConfigFlagEmpty(page: Page, flag: string) { - const configOption = page.locator( - `div.options-table .option-${flag} .option-value-empty`, - ); - await expect(configOption).toHaveText("Not set"); + const configOption = page.locator( + `div.options-table .option-${flag} .option-value-empty`, + ); + await expect(configOption).toHaveText("Not set"); } export async function verifyConfigFlagArray( - page: Page, - config: DeploymentConfig, - flag: string, + page: Page, + config: DeploymentConfig, + flag: string, ) { - const opt = findConfigOption(config, flag); - const configOption = page.locator( - `div.options-table .option-${flag} .option-array`, - ); + const opt = findConfigOption(config, flag); + const configOption = page.locator( + `div.options-table .option-${flag} .option-array`, + ); - // Verify array of options with simple dots - for (const item of opt.value) { - await expect(configOption.locator("li", { hasText: item })).toBeVisible(); - } + // Verify array of options with simple dots + for (const item of opt.value) { + await expect(configOption.locator("li", { hasText: item })).toBeVisible(); + } } export async function verifyConfigFlagEntries( - page: Page, - config: DeploymentConfig, - flag: string, + page: Page, + config: DeploymentConfig, + flag: string, ) { - const opt = findConfigOption(config, flag); - const configOption = page.locator( - `div.options-table .option-${flag} .option-array`, - ); + const opt = findConfigOption(config, flag); + const configOption = page.locator( + `div.options-table .option-${flag} .option-array`, + ); - // Verify array of options with green marks. - Object.entries(opt.value) - .sort((a, b) => a[0].localeCompare(b[0])) - .map(async ([item]) => { - await expect( - configOption.locator(`.option-array-item-${item}.option-enabled`, { - hasText: item, - }), - ).toBeVisible(); - }); + // Verify array of options with green marks. + Object.entries(opt.value) + .sort((a, b) => a[0].localeCompare(b[0])) + .map(async ([item]) => { + await expect( + configOption.locator(`.option-array-item-${item}.option-enabled`, { + hasText: item, + }), + ).toBeVisible(); + }); } export async function verifyConfigFlagDuration( - page: Page, - config: DeploymentConfig, - flag: string, + page: Page, + config: DeploymentConfig, + flag: string, ) { - const opt = findConfigOption(config, flag); - const configOption = page.locator( - `div.options-table .option-${flag} .option-value-string`, - ); - await expect(configOption).toHaveText( - formatDuration( - // intervalToDuration takes ms, so convert nanoseconds to ms - intervalToDuration({ - start: 0, - end: (opt.value as number) / 1e6, - }), - ), - ); + const opt = findConfigOption(config, flag); + const configOption = page.locator( + `div.options-table .option-${flag} .option-value-string`, + ); + await expect(configOption).toHaveText( + formatDuration( + // intervalToDuration takes ms, so convert nanoseconds to ms + intervalToDuration({ + start: 0, + end: (opt.value as number) / 1e6, + }), + ), + ); } export function findConfigOption( - config: DeploymentConfig, - flag: string, + config: DeploymentConfig, + flag: string, ): SerpentOption { - const opt = config.options.find((option) => option.flag === flag); - if (opt === undefined) { - // must be undefined as `false` is expected - throw new Error(`Option with env ${flag} has undefined value.`); - } - return opt; + const opt = config.options.find((option) => option.flag === flag); + if (opt === undefined) { + // must be undefined as `false` is expected + throw new Error(`Option with env ${flag} has undefined value.`); + } + return opt; } diff --git a/site/e2e/constants.ts b/site/e2e/constants.ts index 6c5db90395..3ec01312b6 100644 --- a/site/e2e/constants.ts +++ b/site/e2e/constants.ts @@ -4,8 +4,8 @@ export const coderMain = path.join(__dirname, "../../enterprise/cmd/coder"); // Default port from the server export const coderPort = process.env.CODER_E2E_PORT - ? Number(process.env.CODER_E2E_PORT) - : 3111; + ? Number(process.env.CODER_E2E_PORT) + : 3111; export const prometheusPort = 2114; export const workspaceProxyPort = 3112; @@ -19,23 +19,23 @@ export const password = "SomeSecurePassword!"; export const email = "admin@coder.com"; export const gitAuth = { - deviceProvider: "device", - webProvider: "web", - // These ports need to be hardcoded so that they can be - // used in `playwright.config.ts` to set the environment - // variables for the server. - devicePort: 50515, - webPort: 50516, + deviceProvider: "device", + webProvider: "web", + // These ports need to be hardcoded so that they can be + // used in `playwright.config.ts` to set the environment + // variables for the server. + devicePort: 50515, + webPort: 50516, - authPath: "/auth", - tokenPath: "/token", - codePath: "/code", - validatePath: "/validate", - installationsPath: "/installations", + authPath: "/auth", + tokenPath: "/token", + codePath: "/code", + validatePath: "/validate", + installationsPath: "/installations", }; export const requireEnterpriseTests = Boolean( - process.env.CODER_E2E_REQUIRE_ENTERPRISE_TESTS, + process.env.CODER_E2E_REQUIRE_ENTERPRISE_TESTS, ); export const enterpriseLicense = process.env.CODER_E2E_ENTERPRISE_LICENSE ?? ""; diff --git a/site/e2e/expectUrl.ts b/site/e2e/expectUrl.ts index 6e4380f513..1051089e6e 100644 --- a/site/e2e/expectUrl.ts +++ b/site/e2e/expectUrl.ts @@ -3,35 +3,35 @@ import { type Page, expect } from "@playwright/test"; type PollingOptions = { timeout?: number; intervals?: number[] }; export const expectUrl = expect.extend({ - /** - * toHavePathName is an alternative to `toHaveURL` that won't fail if the URL contains query parameters. - */ - async toHavePathName(page: Page, expected: string, options?: PollingOptions) { - let actual: string = new URL(page.url()).pathname; - let pass: boolean; - try { - await expect - .poll(() => { - actual = new URL(page.url()).pathname; - return actual; - }, options) - .toBe(expected); - pass = true; - } catch { - pass = false; - } + /** + * toHavePathName is an alternative to `toHaveURL` that won't fail if the URL contains query parameters. + */ + async toHavePathName(page: Page, expected: string, options?: PollingOptions) { + let actual: string = new URL(page.url()).pathname; + let pass: boolean; + try { + await expect + .poll(() => { + actual = new URL(page.url()).pathname; + return actual; + }, options) + .toBe(expected); + pass = true; + } catch { + pass = false; + } - return { - name: "toHavePathName", - pass, - actual, - expected, - message: () => - `The page does not have the expected URL pathname.\nExpected: ${ - this.isNot ? "not" : "" - }${this.utils.printExpected( - expected, - )}\nActual: ${this.utils.printReceived(actual)}`, - }; - }, + return { + name: "toHavePathName", + pass, + actual, + expected, + message: () => + `The page does not have the expected URL pathname.\nExpected: ${ + this.isNot ? "not" : "" + }${this.utils.printExpected( + expected, + )}\nActual: ${this.utils.printReceived(actual)}`, + }; + }, }); diff --git a/site/e2e/global.setup.ts b/site/e2e/global.setup.ts index b23f6bbaa1..c18b7dd01e 100644 --- a/site/e2e/global.setup.ts +++ b/site/e2e/global.setup.ts @@ -7,41 +7,41 @@ import { expectUrl } from "./expectUrl"; import { storageState } from "./playwright.config"; test("setup deployment", async ({ page }) => { - await page.goto("/", { waitUntil: "domcontentloaded" }); - await setupApiCalls(page); - const exists = await API.hasFirstUser(); - // First user already exists, abort early. All tests execute this as a dependency, - // if you run multiple tests in the UI, this will fail unless we check this. - if (exists) { - return; - } + await page.goto("/", { waitUntil: "domcontentloaded" }); + await setupApiCalls(page); + const exists = await API.hasFirstUser(); + // First user already exists, abort early. All tests execute this as a dependency, + // if you run multiple tests in the UI, this will fail unless we check this. + if (exists) { + return; + } - // Setup first user - await page.getByLabel(Language.usernameLabel).fill(constants.username); - await page.getByLabel(Language.emailLabel).fill(constants.email); - await page.getByLabel(Language.passwordLabel).fill(constants.password); - await page.getByTestId("create").click(); + // Setup first user + await page.getByLabel(Language.usernameLabel).fill(constants.username); + await page.getByLabel(Language.emailLabel).fill(constants.email); + await page.getByLabel(Language.passwordLabel).fill(constants.password); + await page.getByTestId("create").click(); - await expectUrl(page).toHavePathName("/workspaces"); - await page.context().storageState({ path: storageState }); + await expectUrl(page).toHavePathName("/workspaces"); + await page.context().storageState({ path: storageState }); - await page.getByTestId("button-select-template").isVisible(); + await page.getByTestId("button-select-template").isVisible(); - // Setup license - if (constants.requireEnterpriseTests || constants.enterpriseLicense) { - // Make sure that we have something that looks like a real license - expect(constants.enterpriseLicense).toBeTruthy(); - expect(constants.enterpriseLicense.length).toBeGreaterThan(92); // the signature alone should be this long - expect(constants.enterpriseLicense.split(".").length).toBe(3); // otherwise it's invalid + // Setup license + if (constants.requireEnterpriseTests || constants.enterpriseLicense) { + // Make sure that we have something that looks like a real license + expect(constants.enterpriseLicense).toBeTruthy(); + expect(constants.enterpriseLicense.length).toBeGreaterThan(92); // the signature alone should be this long + expect(constants.enterpriseLicense.split(".").length).toBe(3); // otherwise it's invalid - await page.goto("/deployment/licenses", { waitUntil: "domcontentloaded" }); + await page.goto("/deployment/licenses", { waitUntil: "domcontentloaded" }); - await page.getByText("Add a license").click(); - await page.getByRole("textbox").fill(constants.enterpriseLicense); - await page.getByText("Upload License").click(); + await page.getByText("Add a license").click(); + await page.getByRole("textbox").fill(constants.enterpriseLicense); + await page.getByText("Upload License").click(); - await expect( - page.getByText("You have successfully added a license"), - ).toBeVisible(); - } + await expect( + page.getByText("You have successfully added a license"), + ).toBeVisible(); + } }); diff --git a/site/e2e/helpers.ts b/site/e2e/helpers.ts index fffc602a3d..b0457697bb 100644 --- a/site/e2e/helpers.ts +++ b/site/e2e/helpers.ts @@ -5,907 +5,907 @@ import { Duplex } from "node:stream"; import { type BrowserContext, type Page, expect, test } from "@playwright/test"; import { API } from "api/api"; import type { - UpdateTemplateMeta, - WorkspaceBuildParameter, + UpdateTemplateMeta, + WorkspaceBuildParameter, } from "api/typesGenerated"; import express from "express"; import capitalize from "lodash/capitalize"; import * as ssh from "ssh2"; import { TarWriter } from "utils/tar"; import { - agentPProfPort, - coderMain, - coderPort, - enterpriseLicense, - prometheusPort, - requireEnterpriseTests, - requireTerraformTests, + agentPProfPort, + coderMain, + coderPort, + enterpriseLicense, + prometheusPort, + requireEnterpriseTests, + requireTerraformTests, } from "./constants"; import { expectUrl } from "./expectUrl"; import { - Agent, - type App, - AppSharingLevel, - type ApplyComplete, - type ExternalAuthProviderResource, - type ParseComplete, - type PlanComplete, - type Resource, - Response, - type RichParameter, + Agent, + type App, + AppSharingLevel, + type ApplyComplete, + type ExternalAuthProviderResource, + type ParseComplete, + type PlanComplete, + type Resource, + Response, + type RichParameter, } from "./provisionerGenerated"; // requiresEnterpriseLicense will skip the test if we're not running with an enterprise license export function requiresEnterpriseLicense() { - if (requireEnterpriseTests) { - return; - } + if (requireEnterpriseTests) { + return; + } - test.skip(!enterpriseLicense); + test.skip(!enterpriseLicense); } // requireTerraformProvisioner by default is enabled. export function requireTerraformProvisioner() { - test.skip(!requireTerraformTests); + test.skip(!requireTerraformTests); } // createWorkspace creates a workspace for a template. // It does not wait for it to be running, but it does navigate to the page. export const createWorkspace = async ( - page: Page, - templateName: string, - richParameters: RichParameter[] = [], - buildParameters: WorkspaceBuildParameter[] = [], - useExternalAuthProvider: string | undefined = undefined, + page: Page, + templateName: string, + richParameters: RichParameter[] = [], + buildParameters: WorkspaceBuildParameter[] = [], + useExternalAuthProvider: string | undefined = undefined, ): Promise => { - await page.goto(`/templates/${templateName}/workspace`, { - waitUntil: "domcontentloaded", - }); - await expectUrl(page).toHavePathName(`/templates/${templateName}/workspace`); + await page.goto(`/templates/${templateName}/workspace`, { + waitUntil: "domcontentloaded", + }); + await expectUrl(page).toHavePathName(`/templates/${templateName}/workspace`); - const name = randomName(); - await page.getByLabel("name").fill(name); + const name = randomName(); + await page.getByLabel("name").fill(name); - await fillParameters(page, richParameters, buildParameters); + await fillParameters(page, richParameters, buildParameters); - if (useExternalAuthProvider !== undefined) { - // Create a new context for the popup which will be created when clicking the button - const popupPromise = page.waitForEvent("popup"); + if (useExternalAuthProvider !== undefined) { + // Create a new context for the popup which will be created when clicking the button + const popupPromise = page.waitForEvent("popup"); - // Find the "Login with " button - const externalAuthLoginButton = page - .getByRole("button") - .getByText("Login with GitHub"); - await expect(externalAuthLoginButton).toBeVisible(); + // Find the "Login with " button + const externalAuthLoginButton = page + .getByRole("button") + .getByText("Login with GitHub"); + await expect(externalAuthLoginButton).toBeVisible(); - // Click it - await externalAuthLoginButton.click(); + // Click it + await externalAuthLoginButton.click(); - // Wait for authentication to occur - const popup = await popupPromise; - await popup.waitForSelector("text=You are now authenticated."); - } + // Wait for authentication to occur + const popup = await popupPromise; + await popup.waitForSelector("text=You are now authenticated."); + } - await page.getByTestId("form-submit").click(); + await page.getByTestId("form-submit").click(); - await expectUrl(page).toHavePathName(`/@admin/${name}`); + await expectUrl(page).toHavePathName(`/@admin/${name}`); - await page.waitForSelector("*[data-testid='build-status'] >> text=Running", { - state: "visible", - }); - return name; + await page.waitForSelector("*[data-testid='build-status'] >> text=Running", { + state: "visible", + }); + return name; }; export const verifyParameters = async ( - page: Page, - workspaceName: string, - richParameters: RichParameter[], - expectedBuildParameters: WorkspaceBuildParameter[], + page: Page, + workspaceName: string, + richParameters: RichParameter[], + expectedBuildParameters: WorkspaceBuildParameter[], ) => { - await page.goto(`/@admin/${workspaceName}/settings/parameters`, { - waitUntil: "domcontentloaded", - }); - await expectUrl(page).toHavePathName( - `/@admin/${workspaceName}/settings/parameters`, - ); + await page.goto(`/@admin/${workspaceName}/settings/parameters`, { + waitUntil: "domcontentloaded", + }); + await expectUrl(page).toHavePathName( + `/@admin/${workspaceName}/settings/parameters`, + ); - for (const buildParameter of expectedBuildParameters) { - const richParameter = richParameters.find( - (richParam) => richParam.name === buildParameter.name, - ); - if (!richParameter) { - throw new Error( - "build parameter is expected to be present in rich parameter schema", - ); - } + for (const buildParameter of expectedBuildParameters) { + const richParameter = richParameters.find( + (richParam) => richParam.name === buildParameter.name, + ); + if (!richParameter) { + throw new Error( + "build parameter is expected to be present in rich parameter schema", + ); + } - const parameterLabel = await page.waitForSelector( - `[data-testid='parameter-field-${richParameter.name}']`, - { state: "visible" }, - ); + const parameterLabel = await page.waitForSelector( + `[data-testid='parameter-field-${richParameter.name}']`, + { state: "visible" }, + ); - const muiDisabled = richParameter.mutable ? "" : ".Mui-disabled"; + const muiDisabled = richParameter.mutable ? "" : ".Mui-disabled"; - if (richParameter.type === "bool") { - const parameterField = await parameterLabel.waitForSelector( - `[data-testid='parameter-field-bool'] .MuiRadio-root.Mui-checked${muiDisabled} input`, - ); - const value = await parameterField.inputValue(); - expect(value).toEqual(buildParameter.value); - } else if (richParameter.options.length > 0) { - const parameterField = await parameterLabel.waitForSelector( - `[data-testid='parameter-field-options'] .MuiRadio-root.Mui-checked${muiDisabled} input`, - ); - const value = await parameterField.inputValue(); - expect(value).toEqual(buildParameter.value); - } else if (richParameter.type === "list(string)") { - throw new Error("not implemented yet"); // FIXME - } else { - // text or number - const parameterField = await parameterLabel.waitForSelector( - `[data-testid='parameter-field-text'] input${muiDisabled}`, - ); - const value = await parameterField.inputValue(); - expect(value).toEqual(buildParameter.value); - } - } + if (richParameter.type === "bool") { + const parameterField = await parameterLabel.waitForSelector( + `[data-testid='parameter-field-bool'] .MuiRadio-root.Mui-checked${muiDisabled} input`, + ); + const value = await parameterField.inputValue(); + expect(value).toEqual(buildParameter.value); + } else if (richParameter.options.length > 0) { + const parameterField = await parameterLabel.waitForSelector( + `[data-testid='parameter-field-options'] .MuiRadio-root.Mui-checked${muiDisabled} input`, + ); + const value = await parameterField.inputValue(); + expect(value).toEqual(buildParameter.value); + } else if (richParameter.type === "list(string)") { + throw new Error("not implemented yet"); // FIXME + } else { + // text or number + const parameterField = await parameterLabel.waitForSelector( + `[data-testid='parameter-field-text'] input${muiDisabled}`, + ); + const value = await parameterField.inputValue(); + expect(value).toEqual(buildParameter.value); + } + } }; // StarterTemplates are ids of starter templates that can be used in place of // the responses payload. These starter templates will require real provisioners. export enum StarterTemplates { - STARTER_DOCKER = "docker", + STARTER_DOCKER = "docker", } function isStarterTemplate( - input: EchoProvisionerResponses | StarterTemplates | undefined, + input: EchoProvisionerResponses | StarterTemplates | undefined, ): input is StarterTemplates { - if (!input) { - return false; - } - return typeof input === "string"; + if (!input) { + return false; + } + return typeof input === "string"; } // createTemplate navigates to the /templates/new page and uploads a template // with the resources provided in the responses argument. export const createTemplate = async ( - page: Page, - responses?: EchoProvisionerResponses | StarterTemplates, + page: Page, + responses?: EchoProvisionerResponses | StarterTemplates, ): Promise => { - let path = "/templates/new"; - if (isStarterTemplate(responses)) { - path += `?exampleId=${responses}`; - } else { - // The form page will read this value and use it as the default type. - path += "?provisioner_type=echo"; - } + let path = "/templates/new"; + if (isStarterTemplate(responses)) { + path += `?exampleId=${responses}`; + } else { + // The form page will read this value and use it as the default type. + path += "?provisioner_type=echo"; + } - await page.goto(path, { waitUntil: "domcontentloaded" }); - await expectUrl(page).toHavePathName("/templates/new"); + await page.goto(path, { waitUntil: "domcontentloaded" }); + await expectUrl(page).toHavePathName("/templates/new"); - if (!isStarterTemplate(responses)) { - await page.getByTestId("file-upload").setInputFiles({ - buffer: await createTemplateVersionTar(responses), - mimeType: "application/x-tar", - name: "template.tar", - }); - } + if (!isStarterTemplate(responses)) { + await page.getByTestId("file-upload").setInputFiles({ + buffer: await createTemplateVersionTar(responses), + mimeType: "application/x-tar", + name: "template.tar", + }); + } - const name = randomName(); - await page.getByLabel("Name *").fill(name); - await page.getByTestId("form-submit").click(); - await expectUrl(page).toHavePathName(`/templates/${name}/files`, { - timeout: 30000, - }); - return name; + const name = randomName(); + await page.getByLabel("Name *").fill(name); + await page.getByTestId("form-submit").click(); + await expectUrl(page).toHavePathName(`/templates/${name}/files`, { + timeout: 30000, + }); + return name; }; // createGroup navigates to the /groups/create page and creates a group with a // random name. export const createGroup = async (page: Page): Promise => { - await page.goto("/groups/create", { waitUntil: "domcontentloaded" }); - await expectUrl(page).toHavePathName("/groups/create"); + await page.goto("/groups/create", { waitUntil: "domcontentloaded" }); + await expectUrl(page).toHavePathName("/groups/create"); - const name = randomName(); - await page.getByLabel("Name", { exact: true }).fill(name); - await page.getByTestId("form-submit").click(); - await expect(page).toHaveURL( - /\/groups\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/, - ); - return name; + const name = randomName(); + await page.getByLabel("Name", { exact: true }).fill(name); + await page.getByTestId("form-submit").click(); + await expect(page).toHaveURL( + /\/groups\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/, + ); + return name; }; // sshIntoWorkspace spawns a Coder SSH process and a client connected to it. export const sshIntoWorkspace = async ( - page: Page, - workspace: string, - binaryPath = "go", - binaryArgs: string[] = [], + page: Page, + workspace: string, + binaryPath = "go", + binaryArgs: string[] = [], ): Promise => { - if (binaryPath === "go") { - binaryArgs = ["run", coderMain]; - } - const sessionToken = await findSessionToken(page); - return new Promise((resolve, reject) => { - const cp = spawn(binaryPath, [...binaryArgs, "ssh", "--stdio", workspace], { - env: { - ...process.env, - CODER_SESSION_TOKEN: sessionToken, - CODER_URL: `http://localhost:${coderPort}`, - }, - }); - cp.on("error", (err) => reject(err)); - const proxyStream = new Duplex({ - read: (size) => { - return cp.stdout.read(Math.min(size, cp.stdout.readableLength)); - }, - write: cp.stdin.write.bind(cp.stdin), - }); - // eslint-disable-next-line no-console -- Helpful for debugging - cp.stderr.on("data", (data) => console.log(data.toString())); - cp.stdout.on("readable", (...args) => { - proxyStream.emit("readable", ...args); - if (cp.stdout.readableLength > 0) { - proxyStream.emit("data", cp.stdout.read()); - } - }); - const client = new ssh.Client(); - client.connect({ - sock: proxyStream, - username: "coder", - }); - client.on("error", (err) => reject(err)); - client.on("ready", () => { - resolve(client); - }); - }); + if (binaryPath === "go") { + binaryArgs = ["run", coderMain]; + } + const sessionToken = await findSessionToken(page); + return new Promise((resolve, reject) => { + const cp = spawn(binaryPath, [...binaryArgs, "ssh", "--stdio", workspace], { + env: { + ...process.env, + CODER_SESSION_TOKEN: sessionToken, + CODER_URL: `http://localhost:${coderPort}`, + }, + }); + cp.on("error", (err) => reject(err)); + const proxyStream = new Duplex({ + read: (size) => { + return cp.stdout.read(Math.min(size, cp.stdout.readableLength)); + }, + write: cp.stdin.write.bind(cp.stdin), + }); + // eslint-disable-next-line no-console -- Helpful for debugging + cp.stderr.on("data", (data) => console.log(data.toString())); + cp.stdout.on("readable", (...args) => { + proxyStream.emit("readable", ...args); + if (cp.stdout.readableLength > 0) { + proxyStream.emit("data", cp.stdout.read()); + } + }); + const client = new ssh.Client(); + client.connect({ + sock: proxyStream, + username: "coder", + }); + client.on("error", (err) => reject(err)); + client.on("ready", () => { + resolve(client); + }); + }); }; export const stopWorkspace = async (page: Page, workspaceName: string) => { - await page.goto(`/@admin/${workspaceName}`, { - waitUntil: "domcontentloaded", - }); - await expectUrl(page).toHavePathName(`/@admin/${workspaceName}`); + await page.goto(`/@admin/${workspaceName}`, { + waitUntil: "domcontentloaded", + }); + await expectUrl(page).toHavePathName(`/@admin/${workspaceName}`); - await page.getByTestId("workspace-stop-button").click(); + await page.getByTestId("workspace-stop-button").click(); - await page.waitForSelector("*[data-testid='build-status'] >> text=Stopped", { - state: "visible", - }); + await page.waitForSelector("*[data-testid='build-status'] >> text=Stopped", { + state: "visible", + }); }; export const buildWorkspaceWithParameters = async ( - page: Page, - workspaceName: string, - richParameters: RichParameter[] = [], - buildParameters: WorkspaceBuildParameter[] = [], - confirm = false, + page: Page, + workspaceName: string, + richParameters: RichParameter[] = [], + buildParameters: WorkspaceBuildParameter[] = [], + confirm = false, ) => { - await page.goto(`/@admin/${workspaceName}`, { - waitUntil: "domcontentloaded", - }); - await expectUrl(page).toHavePathName(`/@admin/${workspaceName}`); + await page.goto(`/@admin/${workspaceName}`, { + waitUntil: "domcontentloaded", + }); + await expectUrl(page).toHavePathName(`/@admin/${workspaceName}`); - await page.getByTestId("build-parameters-button").click(); + await page.getByTestId("build-parameters-button").click(); - await fillParameters(page, richParameters, buildParameters); - await page.getByTestId("build-parameters-submit").click(); - if (confirm) { - await page.getByTestId("confirm-button").click(); - } + await fillParameters(page, richParameters, buildParameters); + await page.getByTestId("build-parameters-submit").click(); + if (confirm) { + await page.getByTestId("confirm-button").click(); + } - await page.waitForSelector("*[data-testid='build-status'] >> text=Running", { - state: "visible", - }); + await page.waitForSelector("*[data-testid='build-status'] >> text=Running", { + state: "visible", + }); }; // startAgent runs the coder agent with the provided token. // It awaits the agent to be ready before returning. export const startAgent = async ( - page: Page, - token: string, + page: Page, + token: string, ): Promise => { - return startAgentWithCommand(page, token, "go", "run", coderMain); + return startAgentWithCommand(page, token, "go", "run", coderMain); }; // downloadCoderVersion downloads the version provided into a temporary dir and // caches it so subsequent calls are fast. export const downloadCoderVersion = async ( - version: string, + version: string, ): Promise => { - if (version.startsWith("v")) { - version = version.slice(1); - } + if (version.startsWith("v")) { + version = version.slice(1); + } - const binaryName = `coder-e2e-${version}`; - const tempDir = "/tmp/coder-e2e-cache"; - // The install script adds `./bin` automatically to the path :shrug: - const binaryPath = path.join(tempDir, "bin", binaryName); + const binaryName = `coder-e2e-${version}`; + const tempDir = "/tmp/coder-e2e-cache"; + // The install script adds `./bin` automatically to the path :shrug: + const binaryPath = path.join(tempDir, "bin", binaryName); - const exists = await new Promise((resolve) => { - const cp = spawn(binaryPath, ["version"]); - cp.on("close", (code) => { - resolve(code === 0); - }); - cp.on("error", () => resolve(false)); - }); - if (exists) { - return binaryPath; - } + const exists = await new Promise((resolve) => { + const cp = spawn(binaryPath, ["version"]); + cp.on("close", (code) => { + resolve(code === 0); + }); + cp.on("error", () => resolve(false)); + }); + if (exists) { + return binaryPath; + } - // Run our official install script to install the binary - await new Promise((resolve, reject) => { - const cp = spawn( - path.join(__dirname, "../../install.sh"), - [ - "--version", - version, - "--method", - "standalone", - "--prefix", - tempDir, - "--binary-name", - binaryName, - ], - { - env: { - ...process.env, - XDG_CACHE_HOME: "/tmp/coder-e2e-cache", - TRACE: "1", // tells install.sh to `set -x`, helpful if something goes wrong - }, - }, - ); - // eslint-disable-next-line no-console -- Needed for debugging - cp.stderr.on("data", (data) => console.error(data.toString())); - // eslint-disable-next-line no-console -- Needed for debugging - cp.stdout.on("data", (data) => console.log(data.toString())); - cp.on("close", (code) => { - if (code === 0) { - resolve(); - } else { - reject(new Error(`install.sh failed with code ${code}`)); - } - }); - }); - return binaryPath; + // Run our official install script to install the binary + await new Promise((resolve, reject) => { + const cp = spawn( + path.join(__dirname, "../../install.sh"), + [ + "--version", + version, + "--method", + "standalone", + "--prefix", + tempDir, + "--binary-name", + binaryName, + ], + { + env: { + ...process.env, + XDG_CACHE_HOME: "/tmp/coder-e2e-cache", + TRACE: "1", // tells install.sh to `set -x`, helpful if something goes wrong + }, + }, + ); + // eslint-disable-next-line no-console -- Needed for debugging + cp.stderr.on("data", (data) => console.error(data.toString())); + // eslint-disable-next-line no-console -- Needed for debugging + cp.stdout.on("data", (data) => console.log(data.toString())); + cp.on("close", (code) => { + if (code === 0) { + resolve(); + } else { + reject(new Error(`install.sh failed with code ${code}`)); + } + }); + }); + return binaryPath; }; export const startAgentWithCommand = async ( - page: Page, - token: string, - command: string, - ...args: string[] + page: Page, + token: string, + command: string, + ...args: string[] ): Promise => { - const cp = spawn(command, [...args, "agent", "--no-reap"], { - env: { - ...process.env, - CODER_AGENT_URL: `http://localhost:${coderPort}`, - CODER_AGENT_TOKEN: token, - CODER_AGENT_PPROF_ADDRESS: `127.0.0.1:${agentPProfPort}`, - CODER_AGENT_PROMETHEUS_ADDRESS: `127.0.0.1:${prometheusPort}`, - }, - }); - cp.stdout.on("data", (data: Buffer) => { - // eslint-disable-next-line no-console -- Log agent activity - console.log( - `[agent] [stdout] [onData] ${data.toString().replace(/\n$/g, "")}`, - ); - }); - cp.stderr.on("data", (data: Buffer) => { - // eslint-disable-next-line no-console -- Log agent activity - console.log( - `[agent] [stderr] [onData] ${data.toString().replace(/\n$/g, "")}`, - ); - }); + const cp = spawn(command, [...args, "agent", "--no-reap"], { + env: { + ...process.env, + CODER_AGENT_URL: `http://localhost:${coderPort}`, + CODER_AGENT_TOKEN: token, + CODER_AGENT_PPROF_ADDRESS: `127.0.0.1:${agentPProfPort}`, + CODER_AGENT_PROMETHEUS_ADDRESS: `127.0.0.1:${prometheusPort}`, + }, + }); + cp.stdout.on("data", (data: Buffer) => { + // eslint-disable-next-line no-console -- Log agent activity + console.log( + `[agent] [stdout] [onData] ${data.toString().replace(/\n$/g, "")}`, + ); + }); + cp.stderr.on("data", (data: Buffer) => { + // eslint-disable-next-line no-console -- Log agent activity + console.log( + `[agent] [stderr] [onData] ${data.toString().replace(/\n$/g, "")}`, + ); + }); - await page.getByTestId("agent-status-ready").waitFor({ state: "visible" }); - return cp; + await page.getByTestId("agent-status-ready").waitFor({ state: "visible" }); + return cp; }; export const stopAgent = async (cp: ChildProcess, goRun = true) => { - // When the web server is started with `go run`, it spawns a child process with coder server. - // `pkill -P` terminates child processes belonging the same group as `go run`. - // The command `kill` is used to terminate a web server started as a standalone binary. - exec(goRun ? `pkill -P ${cp.pid}` : `kill ${cp.pid}`, (error) => { - if (error) { - throw new Error(`exec error: ${JSON.stringify(error)}`); - } - }); - await waitUntilUrlIsNotResponding(`http://localhost:${prometheusPort}`); + // When the web server is started with `go run`, it spawns a child process with coder server. + // `pkill -P` terminates child processes belonging the same group as `go run`. + // The command `kill` is used to terminate a web server started as a standalone binary. + exec(goRun ? `pkill -P ${cp.pid}` : `kill ${cp.pid}`, (error) => { + if (error) { + throw new Error(`exec error: ${JSON.stringify(error)}`); + } + }); + await waitUntilUrlIsNotResponding(`http://localhost:${prometheusPort}`); }; export const waitUntilUrlIsNotResponding = async (url: string) => { - const maxRetries = 30; - const retryIntervalMs = 1000; - let retries = 0; + const maxRetries = 30; + const retryIntervalMs = 1000; + let retries = 0; - const axiosInstance = API.getAxiosInstance(); - while (retries < maxRetries) { - try { - await axiosInstance.get(url); - } catch (error) { - return; - } + const axiosInstance = API.getAxiosInstance(); + while (retries < maxRetries) { + try { + await axiosInstance.get(url); + } catch (error) { + return; + } - retries++; - await new Promise((resolve) => setTimeout(resolve, retryIntervalMs)); - } - throw new Error( - `URL ${url} is still responding after ${maxRetries * retryIntervalMs}ms`, - ); + retries++; + await new Promise((resolve) => setTimeout(resolve, retryIntervalMs)); + } + throw new Error( + `URL ${url} is still responding after ${maxRetries * retryIntervalMs}ms`, + ); }; // Allows users to more easily define properties they want for agents and resources! type RecursivePartial = { - [P in keyof T]?: T[P] extends (infer U)[] - ? RecursivePartial[] - : T[P] extends object | undefined - ? RecursivePartial - : T[P]; + [P in keyof T]?: T[P] extends (infer U)[] + ? RecursivePartial[] + : T[P] extends object | undefined + ? RecursivePartial + : T[P]; }; interface EchoProvisionerResponses { - // parse is for observing any Terraform variables - parse?: RecursivePartial[]; - // plan occurs when the template is imported - plan?: RecursivePartial[]; - // apply occurs when the workspace is built - apply?: RecursivePartial[]; + // parse is for observing any Terraform variables + parse?: RecursivePartial[]; + // plan occurs when the template is imported + plan?: RecursivePartial[]; + // apply occurs when the workspace is built + apply?: RecursivePartial[]; } // createTemplateVersionTar consumes a series of echo provisioner protobufs and // converts it into an uploadable tar file. const createTemplateVersionTar = async ( - responses?: EchoProvisionerResponses, + responses?: EchoProvisionerResponses, ): Promise => { - if (!responses) { - responses = {}; - } - if (!responses.parse) { - responses.parse = [ - { - parse: {}, - }, - ]; - } - if (!responses.apply) { - responses.apply = [ - { - apply: {}, - }, - ]; - } - if (!responses.plan) { - responses.plan = responses.apply.map((response) => { - if (response.log) { - return response; - } - return { - plan: { - error: response.apply?.error ?? "", - resources: response.apply?.resources ?? [], - parameters: response.apply?.parameters ?? [], - externalAuthProviders: response.apply?.externalAuthProviders ?? [], - }, - }; - }); - } + if (!responses) { + responses = {}; + } + if (!responses.parse) { + responses.parse = [ + { + parse: {}, + }, + ]; + } + if (!responses.apply) { + responses.apply = [ + { + apply: {}, + }, + ]; + } + if (!responses.plan) { + responses.plan = responses.apply.map((response) => { + if (response.log) { + return response; + } + return { + plan: { + error: response.apply?.error ?? "", + resources: response.apply?.resources ?? [], + parameters: response.apply?.parameters ?? [], + externalAuthProviders: response.apply?.externalAuthProviders ?? [], + }, + }; + }); + } - const tar = new TarWriter(); - responses.parse.forEach((response, index) => { - response.parse = { - templateVariables: [], - error: "", - readme: new Uint8Array(), - workspaceTags: {}, - ...response.parse, - } as ParseComplete; - tar.addFile( - `${index}.parse.protobuf`, - Response.encode(response as Response).finish(), - ); - }); + const tar = new TarWriter(); + responses.parse.forEach((response, index) => { + response.parse = { + templateVariables: [], + error: "", + readme: new Uint8Array(), + workspaceTags: {}, + ...response.parse, + } as ParseComplete; + tar.addFile( + `${index}.parse.protobuf`, + Response.encode(response as Response).finish(), + ); + }); - const fillResource = (resource: RecursivePartial) => { - if (resource.agents) { - resource.agents = resource.agents?.map( - (agent: RecursivePartial) => { - if (agent.apps) { - agent.apps = agent.apps.map((app) => { - return { - command: "", - displayName: "example", - external: false, - icon: "", - sharingLevel: AppSharingLevel.PUBLIC, - slug: "example", - subdomain: false, - url: "", - ...app, - } as App; - }); - } - const agentResource = { - apps: [], - architecture: "amd64", - connectionTimeoutSeconds: 300, - directory: "", - env: {}, - id: randomUUID(), - metadata: [], - extraEnvs: [], - scripts: [], - motdFile: "", - name: "dev", - operatingSystem: "linux", - shutdownScript: "", - shutdownScriptTimeoutSeconds: 0, - startupScript: "", - startupScriptBehavior: "", - startupScriptTimeoutSeconds: 300, - troubleshootingUrl: "", - token: randomUUID(), - ...agent, - } as Agent; + const fillResource = (resource: RecursivePartial) => { + if (resource.agents) { + resource.agents = resource.agents?.map( + (agent: RecursivePartial) => { + if (agent.apps) { + agent.apps = agent.apps.map((app) => { + return { + command: "", + displayName: "example", + external: false, + icon: "", + sharingLevel: AppSharingLevel.PUBLIC, + slug: "example", + subdomain: false, + url: "", + ...app, + } as App; + }); + } + const agentResource = { + apps: [], + architecture: "amd64", + connectionTimeoutSeconds: 300, + directory: "", + env: {}, + id: randomUUID(), + metadata: [], + extraEnvs: [], + scripts: [], + motdFile: "", + name: "dev", + operatingSystem: "linux", + shutdownScript: "", + shutdownScriptTimeoutSeconds: 0, + startupScript: "", + startupScriptBehavior: "", + startupScriptTimeoutSeconds: 300, + troubleshootingUrl: "", + token: randomUUID(), + ...agent, + } as Agent; - try { - Agent.encode(agentResource); - } catch (e) { - let m = "Error: agentResource encode failed, missing defaults?"; - if (e instanceof Error) { - if (!e.stack?.includes(e.message)) { - m += `\n${e.name}: ${e.message}`; - } - m += `\n${e.stack}`; - } else { - m += `\n${e}`; - } - throw new Error(m); - } + try { + Agent.encode(agentResource); + } catch (e) { + let m = "Error: agentResource encode failed, missing defaults?"; + if (e instanceof Error) { + if (!e.stack?.includes(e.message)) { + m += `\n${e.name}: ${e.message}`; + } + m += `\n${e.stack}`; + } else { + m += `\n${e}`; + } + throw new Error(m); + } - return agentResource; - }, - ); - } - return { - agents: [], - dailyCost: 0, - hide: false, - icon: "", - instanceType: "", - metadata: [], - name: "dev", - type: "echo", - ...resource, - } as Resource; - }; + return agentResource; + }, + ); + } + return { + agents: [], + dailyCost: 0, + hide: false, + icon: "", + instanceType: "", + metadata: [], + name: "dev", + type: "echo", + ...resource, + } as Resource; + }; - responses.apply.forEach((response, index) => { - response.apply = { - error: "", - state: new Uint8Array(), - resources: [], - parameters: [], - externalAuthProviders: [], - ...response.apply, - } as ApplyComplete; - response.apply.resources = response.apply.resources?.map(fillResource); + responses.apply.forEach((response, index) => { + response.apply = { + error: "", + state: new Uint8Array(), + resources: [], + parameters: [], + externalAuthProviders: [], + ...response.apply, + } as ApplyComplete; + response.apply.resources = response.apply.resources?.map(fillResource); - tar.addFile( - `${index}.apply.protobuf`, - Response.encode(response as Response).finish(), - ); - }); - responses.plan.forEach((response, index) => { - response.plan = { - error: "", - resources: [], - parameters: [], - externalAuthProviders: [], - ...response.plan, - } as PlanComplete; - response.plan.resources = response.plan.resources?.map(fillResource); + tar.addFile( + `${index}.apply.protobuf`, + Response.encode(response as Response).finish(), + ); + }); + responses.plan.forEach((response, index) => { + response.plan = { + error: "", + resources: [], + parameters: [], + externalAuthProviders: [], + ...response.plan, + } as PlanComplete; + response.plan.resources = response.plan.resources?.map(fillResource); - tar.addFile( - `${index}.plan.protobuf`, - Response.encode(response as Response).finish(), - ); - }); - const tarFile = await tar.write(); - return Buffer.from( - tarFile instanceof Blob ? await tarFile.arrayBuffer() : tarFile, - ); + tar.addFile( + `${index}.plan.protobuf`, + Response.encode(response as Response).finish(), + ); + }); + const tarFile = await tar.write(); + return Buffer.from( + tarFile instanceof Blob ? await tarFile.arrayBuffer() : tarFile, + ); }; export const randomName = () => { - return randomUUID().slice(0, 8); + return randomUUID().slice(0, 8); }; // Awaiter is a helper that allows you to wait for a callback to be called. // It is useful for waiting for events to occur. export class Awaiter { - private promise: Promise; - private callback?: () => void; + private promise: Promise; + private callback?: () => void; - constructor() { - this.promise = new Promise((r) => { - this.callback = r; - }); - } + constructor() { + this.promise = new Promise((r) => { + this.callback = r; + }); + } - public done(): void { - if (this.callback) { - this.callback(); - } else { - this.promise = Promise.resolve(); - } - } + public done(): void { + if (this.callback) { + this.callback(); + } else { + this.promise = Promise.resolve(); + } + } - public wait(): Promise { - return this.promise; - } + public wait(): Promise { + return this.promise; + } } export const createServer = async ( - port: number, + port: number, ): Promise> => { - const e = express(); - // We need to specify the local IP address as the web server - // tends to fail with IPv6 related error: - // listen EADDRINUSE: address already in use :::50516 - await new Promise((r) => e.listen(port, "0.0.0.0", r)); - return e; + const e = express(); + // We need to specify the local IP address as the web server + // tends to fail with IPv6 related error: + // listen EADDRINUSE: address already in use :::50516 + await new Promise((r) => e.listen(port, "0.0.0.0", r)); + return e; }; export const findSessionToken = async (page: Page): Promise => { - const cookies = await page.context().cookies(); - const sessionCookie = cookies.find((c) => c.name === "coder_session_token"); - if (!sessionCookie) { - throw new Error("session token not found"); - } - return sessionCookie.value; + const cookies = await page.context().cookies(); + const sessionCookie = cookies.find((c) => c.name === "coder_session_token"); + if (!sessionCookie) { + throw new Error("session token not found"); + } + return sessionCookie.value; }; export const echoResponsesWithParameters = ( - richParameters: RichParameter[], + richParameters: RichParameter[], ): EchoProvisionerResponses => { - return { - parse: [ - { - parse: {}, - }, - ], - plan: [ - { - plan: { - parameters: richParameters, - }, - }, - ], - apply: [ - { - apply: { - resources: [ - { - name: "example", - }, - ], - }, - }, - ], - }; + return { + parse: [ + { + parse: {}, + }, + ], + plan: [ + { + plan: { + parameters: richParameters, + }, + }, + ], + apply: [ + { + apply: { + resources: [ + { + name: "example", + }, + ], + }, + }, + ], + }; }; export const echoResponsesWithExternalAuth = ( - providers: ExternalAuthProviderResource[], + providers: ExternalAuthProviderResource[], ): EchoProvisionerResponses => { - return { - parse: [ - { - parse: {}, - }, - ], - plan: [ - { - plan: { - externalAuthProviders: providers, - }, - }, - ], - apply: [ - { - apply: { - externalAuthProviders: providers, - resources: [ - { - name: "example", - }, - ], - }, - }, - ], - }; + return { + parse: [ + { + parse: {}, + }, + ], + plan: [ + { + plan: { + externalAuthProviders: providers, + }, + }, + ], + apply: [ + { + apply: { + externalAuthProviders: providers, + resources: [ + { + name: "example", + }, + ], + }, + }, + ], + }; }; export const fillParameters = async ( - page: Page, - richParameters: RichParameter[] = [], - buildParameters: WorkspaceBuildParameter[] = [], + page: Page, + richParameters: RichParameter[] = [], + buildParameters: WorkspaceBuildParameter[] = [], ) => { - for (const buildParameter of buildParameters) { - const richParameter = richParameters.find( - (richParam) => richParam.name === buildParameter.name, - ); - if (!richParameter) { - throw new Error( - "build parameter is expected to be present in rich parameter schema", - ); - } + for (const buildParameter of buildParameters) { + const richParameter = richParameters.find( + (richParam) => richParam.name === buildParameter.name, + ); + if (!richParameter) { + throw new Error( + "build parameter is expected to be present in rich parameter schema", + ); + } - const parameterLabel = await page.waitForSelector( - `[data-testid='parameter-field-${richParameter.name}']`, - { state: "visible" }, - ); + const parameterLabel = await page.waitForSelector( + `[data-testid='parameter-field-${richParameter.name}']`, + { state: "visible" }, + ); - if (richParameter.type === "bool") { - const parameterField = await parameterLabel.waitForSelector( - `[data-testid='parameter-field-bool'] .MuiRadio-root input[value='${buildParameter.value}']`, - ); - await parameterField.click(); - } else if (richParameter.options.length > 0) { - const parameterField = await parameterLabel.waitForSelector( - `[data-testid='parameter-field-options'] .MuiRadio-root input[value='${buildParameter.value}']`, - ); - await parameterField.click(); - } else if (richParameter.type === "list(string)") { - throw new Error("not implemented yet"); // FIXME - } else { - // text or number - const parameterField = await parameterLabel.waitForSelector( - "[data-testid='parameter-field-text'] input", - ); - await parameterField.fill(buildParameter.value); - } - } + if (richParameter.type === "bool") { + const parameterField = await parameterLabel.waitForSelector( + `[data-testid='parameter-field-bool'] .MuiRadio-root input[value='${buildParameter.value}']`, + ); + await parameterField.click(); + } else if (richParameter.options.length > 0) { + const parameterField = await parameterLabel.waitForSelector( + `[data-testid='parameter-field-options'] .MuiRadio-root input[value='${buildParameter.value}']`, + ); + await parameterField.click(); + } else if (richParameter.type === "list(string)") { + throw new Error("not implemented yet"); // FIXME + } else { + // text or number + const parameterField = await parameterLabel.waitForSelector( + "[data-testid='parameter-field-text'] input", + ); + await parameterField.fill(buildParameter.value); + } + } }; export const updateTemplate = async ( - page: Page, - templateName: string, - responses?: EchoProvisionerResponses, + page: Page, + templateName: string, + responses?: EchoProvisionerResponses, ) => { - const tarball = await createTemplateVersionTar(responses); + const tarball = await createTemplateVersionTar(responses); - const sessionToken = await findSessionToken(page); - const child = spawn( - "go", - [ - "run", - coderMain, - "templates", - "push", - "--test.provisioner", - "echo", - "-y", - "-d", - "-", - templateName, - ], - { - env: { - ...process.env, - CODER_SESSION_TOKEN: sessionToken, - CODER_URL: `http://localhost:${coderPort}`, - }, - }, - ); + const sessionToken = await findSessionToken(page); + const child = spawn( + "go", + [ + "run", + coderMain, + "templates", + "push", + "--test.provisioner", + "echo", + "-y", + "-d", + "-", + templateName, + ], + { + env: { + ...process.env, + CODER_SESSION_TOKEN: sessionToken, + CODER_URL: `http://localhost:${coderPort}`, + }, + }, + ); - const uploaded = new Awaiter(); - child.on("exit", (code) => { - if (code === 0) { - uploaded.done(); - return; - } + const uploaded = new Awaiter(); + child.on("exit", (code) => { + if (code === 0) { + uploaded.done(); + return; + } - throw new Error(`coder templates push failed with code ${code}`); - }); + throw new Error(`coder templates push failed with code ${code}`); + }); - child.stdin.write(tarball); - child.stdin.end(); + child.stdin.write(tarball); + child.stdin.end(); - await uploaded.wait(); + await uploaded.wait(); }; export const updateTemplateSettings = async ( - page: Page, - templateName: string, - templateSettingValues: Pick< - UpdateTemplateMeta, - "name" | "display_name" | "description" | "deprecation_message" - >, + page: Page, + templateName: string, + templateSettingValues: Pick< + UpdateTemplateMeta, + "name" | "display_name" | "description" | "deprecation_message" + >, ) => { - await page.goto(`/templates/${templateName}/settings`, { - waitUntil: "domcontentloaded", - }); - await expectUrl(page).toHavePathName(`/templates/${templateName}/settings`); + await page.goto(`/templates/${templateName}/settings`, { + waitUntil: "domcontentloaded", + }); + await expectUrl(page).toHavePathName(`/templates/${templateName}/settings`); - for (const [key, value] of Object.entries(templateSettingValues)) { - // Skip max_port_share_level for now since the frontend is not yet able to handle it - if (key === "max_port_share_level") { - continue; - } - const labelText = capitalize(key).replace("_", " "); - await page.getByLabel(labelText, { exact: true }).fill(value); - } + for (const [key, value] of Object.entries(templateSettingValues)) { + // Skip max_port_share_level for now since the frontend is not yet able to handle it + if (key === "max_port_share_level") { + continue; + } + const labelText = capitalize(key).replace("_", " "); + await page.getByLabel(labelText, { exact: true }).fill(value); + } - await page.getByTestId("form-submit").click(); + await page.getByTestId("form-submit").click(); - const name = templateSettingValues.name ?? templateName; - await expectUrl(page).toHavePathName(`/templates/${name}`); + const name = templateSettingValues.name ?? templateName; + await expectUrl(page).toHavePathName(`/templates/${name}`); }; export const updateWorkspace = async ( - page: Page, - workspaceName: string, - richParameters: RichParameter[] = [], - buildParameters: WorkspaceBuildParameter[] = [], + page: Page, + workspaceName: string, + richParameters: RichParameter[] = [], + buildParameters: WorkspaceBuildParameter[] = [], ) => { - await page.goto(`/@admin/${workspaceName}`, { - waitUntil: "domcontentloaded", - }); - await expectUrl(page).toHavePathName(`/@admin/${workspaceName}`); + await page.goto(`/@admin/${workspaceName}`, { + waitUntil: "domcontentloaded", + }); + await expectUrl(page).toHavePathName(`/@admin/${workspaceName}`); - await page.getByTestId("workspace-update-button").click(); - await page.getByTestId("confirm-button").click(); + await page.getByTestId("workspace-update-button").click(); + await page.getByTestId("confirm-button").click(); - await fillParameters(page, richParameters, buildParameters); - await page.getByTestId("form-submit").click(); + await fillParameters(page, richParameters, buildParameters); + await page.getByTestId("form-submit").click(); - await page.waitForSelector("*[data-testid='build-status'] >> text=Running", { - state: "visible", - }); + await page.waitForSelector("*[data-testid='build-status'] >> text=Running", { + state: "visible", + }); }; export const updateWorkspaceParameters = async ( - page: Page, - workspaceName: string, - richParameters: RichParameter[] = [], - buildParameters: WorkspaceBuildParameter[] = [], + page: Page, + workspaceName: string, + richParameters: RichParameter[] = [], + buildParameters: WorkspaceBuildParameter[] = [], ) => { - await page.goto(`/@admin/${workspaceName}/settings/parameters`, { - waitUntil: "domcontentloaded", - }); - await expectUrl(page).toHavePathName( - `/@admin/${workspaceName}/settings/parameters`, - ); + await page.goto(`/@admin/${workspaceName}/settings/parameters`, { + waitUntil: "domcontentloaded", + }); + await expectUrl(page).toHavePathName( + `/@admin/${workspaceName}/settings/parameters`, + ); - await fillParameters(page, richParameters, buildParameters); - await page.getByTestId("form-submit").click(); + await fillParameters(page, richParameters, buildParameters); + await page.getByTestId("form-submit").click(); - await page.waitForSelector("*[data-testid='build-status'] >> text=Running", { - state: "visible", - }); + await page.waitForSelector("*[data-testid='build-status'] >> text=Running", { + state: "visible", + }); }; export async function openTerminalWindow( - page: Page, - context: BrowserContext, - workspaceName: string, - agentName = "dev", + page: Page, + context: BrowserContext, + workspaceName: string, + agentName = "dev", ): Promise { - // Wait for the web terminal to open in a new tab - const pagePromise = context.waitForEvent("page"); - await page.getByTestId("terminal").click(); - const terminal = await pagePromise; - await terminal.waitForLoadState("domcontentloaded"); + // Wait for the web terminal to open in a new tab + const pagePromise = context.waitForEvent("page"); + await page.getByTestId("terminal").click(); + const terminal = await pagePromise; + await terminal.waitForLoadState("domcontentloaded"); - // Specify that the shell should be `bash`, to prevent inheriting a shell that - // isn't POSIX compatible, such as Fish. - const commandQuery = `?command=${encodeURIComponent("/usr/bin/env bash")}`; - await expectUrl(terminal).toHavePathName( - `/@admin/${workspaceName}.${agentName}/terminal`, - ); - await terminal.goto(`/@admin/${workspaceName}.dev/terminal${commandQuery}`); + // Specify that the shell should be `bash`, to prevent inheriting a shell that + // isn't POSIX compatible, such as Fish. + const commandQuery = `?command=${encodeURIComponent("/usr/bin/env bash")}`; + await expectUrl(terminal).toHavePathName( + `/@admin/${workspaceName}.${agentName}/terminal`, + ); + await terminal.goto(`/@admin/${workspaceName}.dev/terminal${commandQuery}`); - return terminal; + return terminal; } diff --git a/site/e2e/hooks.ts b/site/e2e/hooks.ts index 224e0c2769..5825134987 100644 --- a/site/e2e/hooks.ts +++ b/site/e2e/hooks.ts @@ -3,88 +3,88 @@ import type { BrowserContext, Page } from "@playwright/test"; import { coderPort, gitAuth } from "./constants"; export const beforeCoderTest = async (page: Page) => { - // eslint-disable-next-line no-console -- Show everything that was printed with console.log() - page.on("console", (msg) => console.log(`[onConsole] ${msg.text()}`)); + // eslint-disable-next-line no-console -- Show everything that was printed with console.log() + page.on("console", (msg) => console.log(`[onConsole] ${msg.text()}`)); - page.on("request", (request) => { - if (!isApiCall(request.url())) { - return; - } + page.on("request", (request) => { + if (!isApiCall(request.url())) { + return; + } - // eslint-disable-next-line no-console -- Log HTTP requests for debugging purposes - console.log( - `[onRequest] method=${request.method()} url=${request.url()} postData=${ - request.postData() ? request.postData() : "" - }`, - ); - }); - page.on("response", async (response) => { - if (!isApiCall(response.url())) { - return; - } + // eslint-disable-next-line no-console -- Log HTTP requests for debugging purposes + console.log( + `[onRequest] method=${request.method()} url=${request.url()} postData=${ + request.postData() ? request.postData() : "" + }`, + ); + }); + page.on("response", async (response) => { + if (!isApiCall(response.url())) { + return; + } - const shouldLogResponse = - !response.url().endsWith("/api/v2/deployment/config") && - !response.url().endsWith("/api/v2/debug/health?force=false"); + const shouldLogResponse = + !response.url().endsWith("/api/v2/deployment/config") && + !response.url().endsWith("/api/v2/debug/health?force=false"); - let responseText = ""; - try { - if (shouldLogResponse) { - const buffer = await response.body(); - responseText = buffer.toString("utf-8"); - responseText = responseText.replace(/\n$/g, ""); - } else { - responseText = "skipped..."; - } - } catch (error) { - responseText = "not_available"; - } + let responseText = ""; + try { + if (shouldLogResponse) { + const buffer = await response.body(); + responseText = buffer.toString("utf-8"); + responseText = responseText.replace(/\n$/g, ""); + } else { + responseText = "skipped..."; + } + } catch (error) { + responseText = "not_available"; + } - // eslint-disable-next-line no-console -- Log HTTP requests for debugging purposes - console.log( - `[onResponse] url=${response.url()} status=${response.status()} body=${responseText}`, - ); - }); + // eslint-disable-next-line no-console -- Log HTTP requests for debugging purposes + console.log( + `[onResponse] url=${response.url()} status=${response.status()} body=${responseText}`, + ); + }); }; export const resetExternalAuthKey = async (context: BrowserContext) => { - // Find the session token so we can destroy the external auth link between tests, to ensure valid authentication happens each time. - const cookies = await context.cookies(); - const sessionCookie = cookies.find((c) => c.name === "coder_session_token"); - const options = { - method: "DELETE", - hostname: "127.0.0.1", - port: coderPort, - path: `/api/v2/external-auth/${gitAuth.webProvider}?coder_session_token=${sessionCookie?.value}`, - }; + // Find the session token so we can destroy the external auth link between tests, to ensure valid authentication happens each time. + const cookies = await context.cookies(); + const sessionCookie = cookies.find((c) => c.name === "coder_session_token"); + const options = { + method: "DELETE", + hostname: "127.0.0.1", + port: coderPort, + path: `/api/v2/external-auth/${gitAuth.webProvider}?coder_session_token=${sessionCookie?.value}`, + }; - const req = http.request(options, (res) => { - let data = ""; - res.on("data", (chunk) => { - data += chunk; - }); + const req = http.request(options, (res) => { + let data = ""; + res.on("data", (chunk) => { + data += chunk; + }); - res.on("end", () => { - // Both 200 (key deleted successfully) and 500 (key was not found) are valid responses. - if (res.statusCode !== 200 && res.statusCode !== 500) { - console.error("failed to delete external auth link", data); - throw new Error( - `failed to delete external auth link: HTTP response ${res.statusCode}`, - ); - } - }); - }); + res.on("end", () => { + // Both 200 (key deleted successfully) and 500 (key was not found) are valid responses. + if (res.statusCode !== 200 && res.statusCode !== 500) { + console.error("failed to delete external auth link", data); + throw new Error( + `failed to delete external auth link: HTTP response ${res.statusCode}`, + ); + } + }); + }); - req.on("error", (err) => { - throw err.message; - }); + req.on("error", (err) => { + throw err.message; + }); - req.end(); + req.end(); }; const isApiCall = (urlString: string): boolean => { - const url = new URL(urlString); - const apiPath = "/api/v2"; + const url = new URL(urlString); + const apiPath = "/api/v2"; - return url.pathname.startsWith(apiPath); + return url.pathname.startsWith(apiPath); }; diff --git a/site/e2e/parameters.ts b/site/e2e/parameters.ts index ca014e5d9c..c63ba06dfc 100644 --- a/site/e2e/parameters.ts +++ b/site/e2e/parameters.ts @@ -3,162 +3,162 @@ import type { RichParameter } from "./provisionerGenerated"; // Rich parameters export const emptyParameter: RichParameter = { - name: "", - description: "", - type: "", - mutable: false, - defaultValue: "", - icon: "", - options: [], - validationRegex: "", - validationError: "", - validationMin: undefined, - validationMax: undefined, - validationMonotonic: "", - required: false, - displayName: "", - order: 0, - ephemeral: false, + name: "", + description: "", + type: "", + mutable: false, + defaultValue: "", + icon: "", + options: [], + validationRegex: "", + validationError: "", + validationMin: undefined, + validationMax: undefined, + validationMonotonic: "", + required: false, + displayName: "", + order: 0, + ephemeral: false, }; // firstParameter is mutable string with a default value (parameter value not required). export const firstParameter: RichParameter = { - ...emptyParameter, + ...emptyParameter, - name: "first_parameter", - displayName: "First parameter", - type: "number", - description: "This is first parameter.", - icon: "/emojis/1f310.png", - defaultValue: "123", - mutable: true, - order: 1, + name: "first_parameter", + displayName: "First parameter", + type: "number", + description: "This is first parameter.", + icon: "/emojis/1f310.png", + defaultValue: "123", + mutable: true, + order: 1, }; // secondParameter is immutable string with a default value (parameter value not required). export const secondParameter: RichParameter = { - ...emptyParameter, + ...emptyParameter, - name: "second_parameter", - displayName: "Second parameter", - type: "string", - description: "This is second parameter.", - defaultValue: "abc", - order: 2, + name: "second_parameter", + displayName: "Second parameter", + type: "string", + description: "This is second parameter.", + defaultValue: "abc", + order: 2, }; // thirdParameter is mutable string with an empty default value (parameter value not required). export const thirdParameter: RichParameter = { - ...emptyParameter, + ...emptyParameter, - name: "third_parameter", - type: "string", - description: "This is third parameter.", - defaultValue: "", - mutable: true, - order: 3, + name: "third_parameter", + type: "string", + description: "This is third parameter.", + defaultValue: "", + mutable: true, + order: 3, }; // fourthParameter is immutable boolean with a default "true" value (parameter value not required). export const fourthParameter: RichParameter = { - ...emptyParameter, + ...emptyParameter, - name: "fourth_parameter", - type: "bool", - description: "This is fourth parameter.", - defaultValue: "true", - order: 3, + name: "fourth_parameter", + type: "bool", + description: "This is fourth parameter.", + defaultValue: "true", + order: 3, }; // fifthParameter is immutable "string with options", with a default option selected (parameter value not required). export const fifthParameter: RichParameter = { - ...emptyParameter, + ...emptyParameter, - name: "fifth_parameter", - displayName: "Fifth parameter", - type: "string", - options: [ - { - name: "ABC", - description: "This is ABC", - value: "abc", - icon: "", - }, - { - name: "DEF", - description: "This is DEF", - value: "def", - icon: "", - }, - { - name: "GHI", - description: "This is GHI", - value: "ghi", - icon: "", - }, - ], - description: "This is fifth parameter.", - defaultValue: "def", - order: 3, + name: "fifth_parameter", + displayName: "Fifth parameter", + type: "string", + options: [ + { + name: "ABC", + description: "This is ABC", + value: "abc", + icon: "", + }, + { + name: "DEF", + description: "This is DEF", + value: "def", + icon: "", + }, + { + name: "GHI", + description: "This is GHI", + value: "ghi", + icon: "", + }, + ], + description: "This is fifth parameter.", + defaultValue: "def", + order: 3, }; // sixthParameter is mutable string without a default value (parameter value is required). export const sixthParameter: RichParameter = { - ...emptyParameter, + ...emptyParameter, - name: "sixth_parameter", - displayName: "Sixth parameter", - type: "number", - description: "This is sixth parameter.", - icon: "/emojis/1f310.png", - required: true, - mutable: true, - order: 1, + name: "sixth_parameter", + displayName: "Sixth parameter", + type: "number", + description: "This is sixth parameter.", + icon: "/emojis/1f310.png", + required: true, + mutable: true, + order: 1, }; // seventhParameter is immutable string without a default value (parameter value is required). export const seventhParameter: RichParameter = { - ...emptyParameter, + ...emptyParameter, - name: "seventh_parameter", - displayName: "Seventh parameter", - type: "string", - description: "This is seventh parameter.", - required: true, - order: 1, + name: "seventh_parameter", + displayName: "Seventh parameter", + type: "string", + description: "This is seventh parameter.", + required: true, + order: 1, }; // randParamName returns a new parameter with a random name. // It helps to avoid cross-test interference when user-auto-fill triggers on // the same parameter name. export const randParamName = (p: RichParameter): RichParameter => { - const name = `${p.name}_${Math.random().toString(36).substring(7)}`; - return { ...p, name: name }; + const name = `${p.name}_${Math.random().toString(36).substring(7)}`; + return { ...p, name: name }; }; // Build options export const firstBuildOption: RichParameter = { - ...emptyParameter, + ...emptyParameter, - name: "first_build_option", - displayName: "First build option", - type: "string", - description: "This is first build option.", - icon: "/emojis/1f310.png", - defaultValue: "ABCDEF", - mutable: true, - ephemeral: true, + name: "first_build_option", + displayName: "First build option", + type: "string", + description: "This is first build option.", + icon: "/emojis/1f310.png", + defaultValue: "ABCDEF", + mutable: true, + ephemeral: true, }; export const secondBuildOption: RichParameter = { - ...emptyParameter, + ...emptyParameter, - name: "second_build_option", - displayName: "Second build option", - type: "bool", - description: "This is second build option.", - defaultValue: "false", - mutable: true, - ephemeral: true, + name: "second_build_option", + displayName: "Second build option", + type: "bool", + description: "This is second build option.", + defaultValue: "false", + mutable: true, + ephemeral: true, }; diff --git a/site/e2e/playwright.config.ts b/site/e2e/playwright.config.ts index 51dfce26ef..6d309eab49 100644 --- a/site/e2e/playwright.config.ts +++ b/site/e2e/playwright.config.ts @@ -2,13 +2,13 @@ import { execSync } from "node:child_process"; import * as path from "node:path"; import { defineConfig } from "@playwright/test"; import { - coderMain, - coderPort, - coderdPProfPort, - e2eFakeExperiment1, - e2eFakeExperiment2, - gitAuth, - requireTerraformTests, + coderMain, + coderPort, + coderdPProfPort, + e2eFakeExperiment1, + e2eFakeExperiment2, + gitAuth, + requireTerraformTests, } from "./constants"; export const wsEndpoint = process.env.CODER_E2E_WS_ENDPOINT; @@ -24,141 +24,141 @@ export const storageState = path.join(__dirname, ".auth.json"); let hasTerraform = false; let hasDocker = false; try { - execSync("terraform --version"); - hasTerraform = true; + execSync("terraform --version"); + hasTerraform = true; } catch { - /* empty */ + /* empty */ } try { - execSync("docker --version"); - hasDocker = true; + execSync("docker --version"); + hasDocker = true; } catch { - /* empty */ + /* empty */ } if (!hasTerraform || !hasDocker) { - const msg = `Terraform provisioners require docker & terraform binaries to function. \n${ - hasTerraform - ? "" - : "\tThe `terraform` executable is not present in the runtime environment.\n" - }${ - hasDocker - ? "" - : "\tThe `docker` executable is not present in the runtime environment.\n" - }`; - throw new Error(msg); + const msg = `Terraform provisioners require docker & terraform binaries to function. \n${ + hasTerraform + ? "" + : "\tThe `terraform` executable is not present in the runtime environment.\n" + }${ + hasDocker + ? "" + : "\tThe `docker` executable is not present in the runtime environment.\n" + }`; + throw new Error(msg); } const localURL = (port: number, path: string): string => { - return `http://localhost:${port}${path}`; + return `http://localhost:${port}${path}`; }; export default defineConfig({ - projects: [ - { - name: "testsSetup", - testMatch: /global.setup\.ts/, - }, - { - name: "tests", - testMatch: /.*\.spec\.ts/, - dependencies: ["testsSetup"], - use: { storageState }, - timeout: 50_000, - }, - ], - reporter: [["./reporter.ts"]], - use: { - baseURL: `http://localhost:${coderPort}`, - video: "retain-on-failure", - ...(wsEndpoint - ? { - connectOptions: { - wsEndpoint: wsEndpoint, - }, - } - : { - launchOptions: { - args: ["--disable-webgl"], - }, - }), - }, - webServer: { - url: `http://localhost:${coderPort}/api/v2/deployment/config`, - command: [ - `go run -tags embed ${coderMain} server`, - "--global-config $(mktemp -d -t e2e-XXXXXXXXXX)", - `--access-url=http://localhost:${coderPort}`, - `--http-address=0.0.0.0:${coderPort}`, - "--in-memory", - "--telemetry=false", - "--dangerous-disable-rate-limits", - "--provisioner-daemons 10", - // TODO: Enable some terraform provisioners - `--provisioner-types=echo${requireTerraformTests ? ",terraform" : ""}`, - "--provisioner-daemons=10", - "--web-terminal-renderer=dom", - "--pprof-enable", - ] - .filter(Boolean) - .join(" "), - env: { - ...process.env, - // Otherwise, the runner fails on Mac with: could not determine kind of name for C.uuid_string_t - CGO_ENABLED: "0", + projects: [ + { + name: "testsSetup", + testMatch: /global.setup\.ts/, + }, + { + name: "tests", + testMatch: /.*\.spec\.ts/, + dependencies: ["testsSetup"], + use: { storageState }, + timeout: 50_000, + }, + ], + reporter: [["./reporter.ts"]], + use: { + baseURL: `http://localhost:${coderPort}`, + video: "retain-on-failure", + ...(wsEndpoint + ? { + connectOptions: { + wsEndpoint: wsEndpoint, + }, + } + : { + launchOptions: { + args: ["--disable-webgl"], + }, + }), + }, + webServer: { + url: `http://localhost:${coderPort}/api/v2/deployment/config`, + command: [ + `go run -tags embed ${coderMain} server`, + "--global-config $(mktemp -d -t e2e-XXXXXXXXXX)", + `--access-url=http://localhost:${coderPort}`, + `--http-address=0.0.0.0:${coderPort}`, + "--in-memory", + "--telemetry=false", + "--dangerous-disable-rate-limits", + "--provisioner-daemons 10", + // TODO: Enable some terraform provisioners + `--provisioner-types=echo${requireTerraformTests ? ",terraform" : ""}`, + "--provisioner-daemons=10", + "--web-terminal-renderer=dom", + "--pprof-enable", + ] + .filter(Boolean) + .join(" "), + env: { + ...process.env, + // Otherwise, the runner fails on Mac with: could not determine kind of name for C.uuid_string_t + CGO_ENABLED: "0", - // This is the test provider for git auth with devices! - CODER_GITAUTH_0_ID: gitAuth.deviceProvider, - CODER_GITAUTH_0_TYPE: "github", - CODER_GITAUTH_0_CLIENT_ID: "client", - CODER_GITAUTH_0_CLIENT_SECRET: "secret", - CODER_GITAUTH_0_DEVICE_FLOW: "true", - CODER_GITAUTH_0_APP_INSTALL_URL: - "https://github.com/apps/coder/installations/new", - CODER_GITAUTH_0_APP_INSTALLATIONS_URL: localURL( - gitAuth.devicePort, - gitAuth.installationsPath, - ), - CODER_GITAUTH_0_TOKEN_URL: localURL( - gitAuth.devicePort, - gitAuth.tokenPath, - ), - CODER_GITAUTH_0_DEVICE_CODE_URL: localURL( - gitAuth.devicePort, - gitAuth.codePath, - ), - CODER_GITAUTH_0_VALIDATE_URL: localURL( - gitAuth.devicePort, - gitAuth.validatePath, - ), + // This is the test provider for git auth with devices! + CODER_GITAUTH_0_ID: gitAuth.deviceProvider, + CODER_GITAUTH_0_TYPE: "github", + CODER_GITAUTH_0_CLIENT_ID: "client", + CODER_GITAUTH_0_CLIENT_SECRET: "secret", + CODER_GITAUTH_0_DEVICE_FLOW: "true", + CODER_GITAUTH_0_APP_INSTALL_URL: + "https://github.com/apps/coder/installations/new", + CODER_GITAUTH_0_APP_INSTALLATIONS_URL: localURL( + gitAuth.devicePort, + gitAuth.installationsPath, + ), + CODER_GITAUTH_0_TOKEN_URL: localURL( + gitAuth.devicePort, + gitAuth.tokenPath, + ), + CODER_GITAUTH_0_DEVICE_CODE_URL: localURL( + gitAuth.devicePort, + gitAuth.codePath, + ), + CODER_GITAUTH_0_VALIDATE_URL: localURL( + gitAuth.devicePort, + gitAuth.validatePath, + ), - CODER_GITAUTH_1_ID: gitAuth.webProvider, - CODER_GITAUTH_1_TYPE: "github", - CODER_GITAUTH_1_CLIENT_ID: "client", - CODER_GITAUTH_1_CLIENT_SECRET: "secret", - CODER_GITAUTH_1_AUTH_URL: localURL(gitAuth.webPort, gitAuth.authPath), - CODER_GITAUTH_1_TOKEN_URL: localURL(gitAuth.webPort, gitAuth.tokenPath), - CODER_GITAUTH_1_DEVICE_CODE_URL: localURL( - gitAuth.webPort, - gitAuth.codePath, - ), - CODER_GITAUTH_1_VALIDATE_URL: localURL( - gitAuth.webPort, - gitAuth.validatePath, - ), - CODER_PPROF_ADDRESS: `127.0.0.1:${coderdPProfPort}`, - CODER_EXPERIMENTS: `multi-organization,${e2eFakeExperiment1},${e2eFakeExperiment2}`, + CODER_GITAUTH_1_ID: gitAuth.webProvider, + CODER_GITAUTH_1_TYPE: "github", + CODER_GITAUTH_1_CLIENT_ID: "client", + CODER_GITAUTH_1_CLIENT_SECRET: "secret", + CODER_GITAUTH_1_AUTH_URL: localURL(gitAuth.webPort, gitAuth.authPath), + CODER_GITAUTH_1_TOKEN_URL: localURL(gitAuth.webPort, gitAuth.tokenPath), + CODER_GITAUTH_1_DEVICE_CODE_URL: localURL( + gitAuth.webPort, + gitAuth.codePath, + ), + CODER_GITAUTH_1_VALIDATE_URL: localURL( + gitAuth.webPort, + gitAuth.validatePath, + ), + CODER_PPROF_ADDRESS: `127.0.0.1:${coderdPProfPort}`, + CODER_EXPERIMENTS: `multi-organization,${e2eFakeExperiment1},${e2eFakeExperiment2}`, - // Tests for Deployment / User Authentication / OIDC - CODER_OIDC_ISSUER_URL: "https://accounts.google.com", - CODER_OIDC_EMAIL_DOMAIN: "coder.com", - CODER_OIDC_CLIENT_ID: "1234567890", - CODER_OIDC_CLIENT_SECRET: "1234567890Secret", - CODER_OIDC_ALLOW_SIGNUPS: "false", - CODER_OIDC_SIGN_IN_TEXT: "Hello", - CODER_OIDC_ICON_URL: "/icon/google.svg", - }, - reuseExistingServer: false, - }, + // Tests for Deployment / User Authentication / OIDC + CODER_OIDC_ISSUER_URL: "https://accounts.google.com", + CODER_OIDC_EMAIL_DOMAIN: "coder.com", + CODER_OIDC_CLIENT_ID: "1234567890", + CODER_OIDC_CLIENT_SECRET: "1234567890Secret", + CODER_OIDC_ALLOW_SIGNUPS: "false", + CODER_OIDC_SIGN_IN_TEXT: "Hello", + CODER_OIDC_ICON_URL: "/icon/google.svg", + }, + reuseExistingServer: false, + }, }); diff --git a/site/e2e/provisionerGenerated.ts b/site/e2e/provisionerGenerated.ts index fa98b21b7f..9168d4b69b 100644 --- a/site/e2e/provisionerGenerated.ts +++ b/site/e2e/provisionerGenerated.ts @@ -6,27 +6,27 @@ export const protobufPackage = "provisioner"; /** LogLevel represents severity of the log. */ export enum LogLevel { - TRACE = 0, - DEBUG = 1, - INFO = 2, - WARN = 3, - ERROR = 4, - UNRECOGNIZED = -1, + TRACE = 0, + DEBUG = 1, + INFO = 2, + WARN = 3, + ERROR = 4, + UNRECOGNIZED = -1, } export enum AppSharingLevel { - OWNER = 0, - AUTHENTICATED = 1, - PUBLIC = 2, - UNRECOGNIZED = -1, + OWNER = 0, + AUTHENTICATED = 1, + PUBLIC = 2, + UNRECOGNIZED = -1, } /** WorkspaceTransition is the desired outcome of a build */ export enum WorkspaceTransition { - START = 0, - STOP = 1, - DESTROY = 2, - UNRECOGNIZED = -1, + START = 0, + STOP = 1, + DESTROY = 2, + UNRECOGNIZED = -1, } /** Empty indicates a successful request/response. */ @@ -34,215 +34,215 @@ export interface Empty {} /** TemplateVariable represents a Terraform variable. */ export interface TemplateVariable { - name: string; - description: string; - type: string; - defaultValue: string; - required: boolean; - sensitive: boolean; + name: string; + description: string; + type: string; + defaultValue: string; + required: boolean; + sensitive: boolean; } /** RichParameterOption represents a singular option that a parameter may expose. */ export interface RichParameterOption { - name: string; - description: string; - value: string; - icon: string; + name: string; + description: string; + value: string; + icon: string; } /** RichParameter represents a variable that is exposed. */ export interface RichParameter { - name: string; - description: string; - type: string; - mutable: boolean; - defaultValue: string; - icon: string; - options: RichParameterOption[]; - validationRegex: string; - validationError: string; - validationMin?: number | undefined; - validationMax?: number | undefined; - validationMonotonic: string; - required: boolean; - /** legacy_variable_name was removed (= 14) */ - displayName: string; - order: number; - ephemeral: boolean; + name: string; + description: string; + type: string; + mutable: boolean; + defaultValue: string; + icon: string; + options: RichParameterOption[]; + validationRegex: string; + validationError: string; + validationMin?: number | undefined; + validationMax?: number | undefined; + validationMonotonic: string; + required: boolean; + /** legacy_variable_name was removed (= 14) */ + displayName: string; + order: number; + ephemeral: boolean; } /** RichParameterValue holds the key/value mapping of a parameter. */ export interface RichParameterValue { - name: string; - value: string; + name: string; + value: string; } /** VariableValue holds the key/value mapping of a Terraform variable. */ export interface VariableValue { - name: string; - value: string; - sensitive: boolean; + name: string; + value: string; + sensitive: boolean; } /** Log represents output from a request. */ export interface Log { - level: LogLevel; - output: string; + level: LogLevel; + output: string; } export interface InstanceIdentityAuth { - instanceId: string; + instanceId: string; } export interface ExternalAuthProviderResource { - id: string; - optional: boolean; + id: string; + optional: boolean; } export interface ExternalAuthProvider { - id: string; - accessToken: string; + id: string; + accessToken: string; } /** Agent represents a running agent on the workspace. */ export interface Agent { - id: string; - name: string; - env: { [key: string]: string }; - /** Field 4 was startup_script, now removed. */ - operatingSystem: string; - architecture: string; - directory: string; - apps: App[]; - token?: string | undefined; - instanceId?: string | undefined; - connectionTimeoutSeconds: number; - troubleshootingUrl: string; - motdFile: string; - /** - * Field 14 was bool login_before_ready = 14, now removed. - * Field 15, 16, 17 were related to scripts, which are now removed. - */ - metadata: Agent_Metadata[]; - /** Field 19 was startup_script_behavior, now removed. */ - displayApps: DisplayApps | undefined; - scripts: Script[]; - extraEnvs: Env[]; - order: number; + id: string; + name: string; + env: { [key: string]: string }; + /** Field 4 was startup_script, now removed. */ + operatingSystem: string; + architecture: string; + directory: string; + apps: App[]; + token?: string | undefined; + instanceId?: string | undefined; + connectionTimeoutSeconds: number; + troubleshootingUrl: string; + motdFile: string; + /** + * Field 14 was bool login_before_ready = 14, now removed. + * Field 15, 16, 17 were related to scripts, which are now removed. + */ + metadata: Agent_Metadata[]; + /** Field 19 was startup_script_behavior, now removed. */ + displayApps: DisplayApps | undefined; + scripts: Script[]; + extraEnvs: Env[]; + order: number; } export interface Agent_Metadata { - key: string; - displayName: string; - script: string; - interval: number; - timeout: number; - order: number; + key: string; + displayName: string; + script: string; + interval: number; + timeout: number; + order: number; } export interface Agent_EnvEntry { - key: string; - value: string; + key: string; + value: string; } export interface DisplayApps { - vscode: boolean; - vscodeInsiders: boolean; - webTerminal: boolean; - sshHelper: boolean; - portForwardingHelper: boolean; + vscode: boolean; + vscodeInsiders: boolean; + webTerminal: boolean; + sshHelper: boolean; + portForwardingHelper: boolean; } export interface Env { - name: string; - value: string; + name: string; + value: string; } /** Script represents a script to be run on the workspace. */ export interface Script { - displayName: string; - icon: string; - script: string; - cron: string; - startBlocksLogin: boolean; - runOnStart: boolean; - runOnStop: boolean; - timeoutSeconds: number; - logPath: string; + displayName: string; + icon: string; + script: string; + cron: string; + startBlocksLogin: boolean; + runOnStart: boolean; + runOnStop: boolean; + timeoutSeconds: number; + logPath: string; } /** App represents a dev-accessible application on the workspace. */ export interface App { - /** - * slug is the unique identifier for the app, usually the name from the - * template. It must be URL-safe and hostname-safe. - */ - slug: string; - displayName: string; - command: string; - url: string; - icon: string; - subdomain: boolean; - healthcheck: Healthcheck | undefined; - sharingLevel: AppSharingLevel; - external: boolean; - order: number; + /** + * slug is the unique identifier for the app, usually the name from the + * template. It must be URL-safe and hostname-safe. + */ + slug: string; + displayName: string; + command: string; + url: string; + icon: string; + subdomain: boolean; + healthcheck: Healthcheck | undefined; + sharingLevel: AppSharingLevel; + external: boolean; + order: number; } /** Healthcheck represents configuration for checking for app readiness. */ export interface Healthcheck { - url: string; - interval: number; - threshold: number; + url: string; + interval: number; + threshold: number; } /** Resource represents created infrastructure. */ export interface Resource { - name: string; - type: string; - agents: Agent[]; - metadata: Resource_Metadata[]; - hide: boolean; - icon: string; - instanceType: string; - dailyCost: number; + name: string; + type: string; + agents: Agent[]; + metadata: Resource_Metadata[]; + hide: boolean; + icon: string; + instanceType: string; + dailyCost: number; } export interface Resource_Metadata { - key: string; - value: string; - sensitive: boolean; - isNull: boolean; + key: string; + value: string; + sensitive: boolean; + isNull: boolean; } /** Metadata is information about a workspace used in the execution of a build */ export interface Metadata { - coderUrl: string; - workspaceTransition: WorkspaceTransition; - workspaceName: string; - workspaceOwner: string; - workspaceId: string; - workspaceOwnerId: string; - workspaceOwnerEmail: string; - templateName: string; - templateVersion: string; - workspaceOwnerOidcAccessToken: string; - workspaceOwnerSessionToken: string; - templateId: string; - workspaceOwnerName: string; - workspaceOwnerGroups: string[]; - workspaceOwnerSshPublicKey: string; - workspaceOwnerSshPrivateKey: string; - workspaceBuildId: string; + coderUrl: string; + workspaceTransition: WorkspaceTransition; + workspaceName: string; + workspaceOwner: string; + workspaceId: string; + workspaceOwnerId: string; + workspaceOwnerEmail: string; + templateName: string; + templateVersion: string; + workspaceOwnerOidcAccessToken: string; + workspaceOwnerSessionToken: string; + templateId: string; + workspaceOwnerName: string; + workspaceOwnerGroups: string[]; + workspaceOwnerSshPublicKey: string; + workspaceOwnerSshPrivateKey: string; + workspaceBuildId: string; } /** Config represents execution configuration shared by all subsequent requests in the Session */ export interface Config { - /** template_source_archive is a tar of the template source files */ - templateSourceArchive: Uint8Array; - /** state is the provisioner state (if any) */ - state: Uint8Array; - provisionerLogLevel: string; + /** template_source_archive is a tar of the template source files */ + templateSourceArchive: Uint8Array; + /** state is the provisioner state (if any) */ + state: Uint8Array; + provisionerLogLevel: string; } /** ParseRequest consumes source-code to produce inputs. */ @@ -250,31 +250,31 @@ export interface ParseRequest {} /** ParseComplete indicates a request to parse completed. */ export interface ParseComplete { - error: string; - templateVariables: TemplateVariable[]; - readme: Uint8Array; - workspaceTags: { [key: string]: string }; + error: string; + templateVariables: TemplateVariable[]; + readme: Uint8Array; + workspaceTags: { [key: string]: string }; } export interface ParseComplete_WorkspaceTagsEntry { - key: string; - value: string; + key: string; + value: string; } /** PlanRequest asks the provisioner to plan what resources & parameters it will create */ export interface PlanRequest { - metadata: Metadata | undefined; - richParameterValues: RichParameterValue[]; - variableValues: VariableValue[]; - externalAuthProviders: ExternalAuthProvider[]; + metadata: Metadata | undefined; + richParameterValues: RichParameterValue[]; + variableValues: VariableValue[]; + externalAuthProviders: ExternalAuthProvider[]; } /** PlanComplete indicates a request to plan completed. */ export interface PlanComplete { - error: string; - resources: Resource[]; - parameters: RichParameter[]; - externalAuthProviders: ExternalAuthProviderResource[]; + error: string; + resources: Resource[]; + parameters: RichParameter[]; + externalAuthProviders: ExternalAuthProviderResource[]; } /** @@ -282,798 +282,798 @@ export interface PlanComplete { * in the same Session. The plan data is not transmitted over the wire and is cached by the provisioner in the Session. */ export interface ApplyRequest { - metadata: Metadata | undefined; + metadata: Metadata | undefined; } /** ApplyComplete indicates a request to apply completed. */ export interface ApplyComplete { - state: Uint8Array; - error: string; - resources: Resource[]; - parameters: RichParameter[]; - externalAuthProviders: ExternalAuthProviderResource[]; + state: Uint8Array; + error: string; + resources: Resource[]; + parameters: RichParameter[]; + externalAuthProviders: ExternalAuthProviderResource[]; } /** CancelRequest requests that the previous request be canceled gracefully. */ export interface CancelRequest {} export interface Request { - config?: Config | undefined; - parse?: ParseRequest | undefined; - plan?: PlanRequest | undefined; - apply?: ApplyRequest | undefined; - cancel?: CancelRequest | undefined; + config?: Config | undefined; + parse?: ParseRequest | undefined; + plan?: PlanRequest | undefined; + apply?: ApplyRequest | undefined; + cancel?: CancelRequest | undefined; } export interface Response { - log?: Log | undefined; - parse?: ParseComplete | undefined; - plan?: PlanComplete | undefined; - apply?: ApplyComplete | undefined; + log?: Log | undefined; + parse?: ParseComplete | undefined; + plan?: PlanComplete | undefined; + apply?: ApplyComplete | undefined; } export const Empty = { - encode(_: Empty, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { - return writer; - }, + encode(_: Empty, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + return writer; + }, }; export const TemplateVariable = { - encode( - message: TemplateVariable, - writer: _m0.Writer = _m0.Writer.create(), - ): _m0.Writer { - if (message.name !== "") { - writer.uint32(10).string(message.name); - } - if (message.description !== "") { - writer.uint32(18).string(message.description); - } - if (message.type !== "") { - writer.uint32(26).string(message.type); - } - if (message.defaultValue !== "") { - writer.uint32(34).string(message.defaultValue); - } - if (message.required === true) { - writer.uint32(40).bool(message.required); - } - if (message.sensitive === true) { - writer.uint32(48).bool(message.sensitive); - } - return writer; - }, + encode( + message: TemplateVariable, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.name !== "") { + writer.uint32(10).string(message.name); + } + if (message.description !== "") { + writer.uint32(18).string(message.description); + } + if (message.type !== "") { + writer.uint32(26).string(message.type); + } + if (message.defaultValue !== "") { + writer.uint32(34).string(message.defaultValue); + } + if (message.required === true) { + writer.uint32(40).bool(message.required); + } + if (message.sensitive === true) { + writer.uint32(48).bool(message.sensitive); + } + return writer; + }, }; export const RichParameterOption = { - encode( - message: RichParameterOption, - writer: _m0.Writer = _m0.Writer.create(), - ): _m0.Writer { - if (message.name !== "") { - writer.uint32(10).string(message.name); - } - if (message.description !== "") { - writer.uint32(18).string(message.description); - } - if (message.value !== "") { - writer.uint32(26).string(message.value); - } - if (message.icon !== "") { - writer.uint32(34).string(message.icon); - } - return writer; - }, + encode( + message: RichParameterOption, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.name !== "") { + writer.uint32(10).string(message.name); + } + if (message.description !== "") { + writer.uint32(18).string(message.description); + } + if (message.value !== "") { + writer.uint32(26).string(message.value); + } + if (message.icon !== "") { + writer.uint32(34).string(message.icon); + } + return writer; + }, }; export const RichParameter = { - encode( - message: RichParameter, - writer: _m0.Writer = _m0.Writer.create(), - ): _m0.Writer { - if (message.name !== "") { - writer.uint32(10).string(message.name); - } - if (message.description !== "") { - writer.uint32(18).string(message.description); - } - if (message.type !== "") { - writer.uint32(26).string(message.type); - } - if (message.mutable === true) { - writer.uint32(32).bool(message.mutable); - } - if (message.defaultValue !== "") { - writer.uint32(42).string(message.defaultValue); - } - if (message.icon !== "") { - writer.uint32(50).string(message.icon); - } - for (const v of message.options) { - RichParameterOption.encode(v!, writer.uint32(58).fork()).ldelim(); - } - if (message.validationRegex !== "") { - writer.uint32(66).string(message.validationRegex); - } - if (message.validationError !== "") { - writer.uint32(74).string(message.validationError); - } - if (message.validationMin !== undefined) { - writer.uint32(80).int32(message.validationMin); - } - if (message.validationMax !== undefined) { - writer.uint32(88).int32(message.validationMax); - } - if (message.validationMonotonic !== "") { - writer.uint32(98).string(message.validationMonotonic); - } - if (message.required === true) { - writer.uint32(104).bool(message.required); - } - if (message.displayName !== "") { - writer.uint32(122).string(message.displayName); - } - if (message.order !== 0) { - writer.uint32(128).int32(message.order); - } - if (message.ephemeral === true) { - writer.uint32(136).bool(message.ephemeral); - } - return writer; - }, + encode( + message: RichParameter, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.name !== "") { + writer.uint32(10).string(message.name); + } + if (message.description !== "") { + writer.uint32(18).string(message.description); + } + if (message.type !== "") { + writer.uint32(26).string(message.type); + } + if (message.mutable === true) { + writer.uint32(32).bool(message.mutable); + } + if (message.defaultValue !== "") { + writer.uint32(42).string(message.defaultValue); + } + if (message.icon !== "") { + writer.uint32(50).string(message.icon); + } + for (const v of message.options) { + RichParameterOption.encode(v!, writer.uint32(58).fork()).ldelim(); + } + if (message.validationRegex !== "") { + writer.uint32(66).string(message.validationRegex); + } + if (message.validationError !== "") { + writer.uint32(74).string(message.validationError); + } + if (message.validationMin !== undefined) { + writer.uint32(80).int32(message.validationMin); + } + if (message.validationMax !== undefined) { + writer.uint32(88).int32(message.validationMax); + } + if (message.validationMonotonic !== "") { + writer.uint32(98).string(message.validationMonotonic); + } + if (message.required === true) { + writer.uint32(104).bool(message.required); + } + if (message.displayName !== "") { + writer.uint32(122).string(message.displayName); + } + if (message.order !== 0) { + writer.uint32(128).int32(message.order); + } + if (message.ephemeral === true) { + writer.uint32(136).bool(message.ephemeral); + } + return writer; + }, }; export const RichParameterValue = { - encode( - message: RichParameterValue, - writer: _m0.Writer = _m0.Writer.create(), - ): _m0.Writer { - if (message.name !== "") { - writer.uint32(10).string(message.name); - } - if (message.value !== "") { - writer.uint32(18).string(message.value); - } - return writer; - }, + encode( + message: RichParameterValue, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.name !== "") { + writer.uint32(10).string(message.name); + } + if (message.value !== "") { + writer.uint32(18).string(message.value); + } + return writer; + }, }; export const VariableValue = { - encode( - message: VariableValue, - writer: _m0.Writer = _m0.Writer.create(), - ): _m0.Writer { - if (message.name !== "") { - writer.uint32(10).string(message.name); - } - if (message.value !== "") { - writer.uint32(18).string(message.value); - } - if (message.sensitive === true) { - writer.uint32(24).bool(message.sensitive); - } - return writer; - }, + encode( + message: VariableValue, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.name !== "") { + writer.uint32(10).string(message.name); + } + if (message.value !== "") { + writer.uint32(18).string(message.value); + } + if (message.sensitive === true) { + writer.uint32(24).bool(message.sensitive); + } + return writer; + }, }; export const Log = { - encode(message: Log, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { - if (message.level !== 0) { - writer.uint32(8).int32(message.level); - } - if (message.output !== "") { - writer.uint32(18).string(message.output); - } - return writer; - }, + encode(message: Log, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.level !== 0) { + writer.uint32(8).int32(message.level); + } + if (message.output !== "") { + writer.uint32(18).string(message.output); + } + return writer; + }, }; export const InstanceIdentityAuth = { - encode( - message: InstanceIdentityAuth, - writer: _m0.Writer = _m0.Writer.create(), - ): _m0.Writer { - if (message.instanceId !== "") { - writer.uint32(10).string(message.instanceId); - } - return writer; - }, + encode( + message: InstanceIdentityAuth, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.instanceId !== "") { + writer.uint32(10).string(message.instanceId); + } + return writer; + }, }; export const ExternalAuthProviderResource = { - encode( - message: ExternalAuthProviderResource, - writer: _m0.Writer = _m0.Writer.create(), - ): _m0.Writer { - if (message.id !== "") { - writer.uint32(10).string(message.id); - } - if (message.optional === true) { - writer.uint32(16).bool(message.optional); - } - return writer; - }, + encode( + message: ExternalAuthProviderResource, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.id !== "") { + writer.uint32(10).string(message.id); + } + if (message.optional === true) { + writer.uint32(16).bool(message.optional); + } + return writer; + }, }; export const ExternalAuthProvider = { - encode( - message: ExternalAuthProvider, - writer: _m0.Writer = _m0.Writer.create(), - ): _m0.Writer { - if (message.id !== "") { - writer.uint32(10).string(message.id); - } - if (message.accessToken !== "") { - writer.uint32(18).string(message.accessToken); - } - return writer; - }, + encode( + message: ExternalAuthProvider, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.id !== "") { + writer.uint32(10).string(message.id); + } + if (message.accessToken !== "") { + writer.uint32(18).string(message.accessToken); + } + return writer; + }, }; export const Agent = { - encode(message: Agent, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { - if (message.id !== "") { - writer.uint32(10).string(message.id); - } - if (message.name !== "") { - writer.uint32(18).string(message.name); - } - Object.entries(message.env).forEach(([key, value]) => { - Agent_EnvEntry.encode( - { key: key as any, value }, - writer.uint32(26).fork(), - ).ldelim(); - }); - if (message.operatingSystem !== "") { - writer.uint32(42).string(message.operatingSystem); - } - if (message.architecture !== "") { - writer.uint32(50).string(message.architecture); - } - if (message.directory !== "") { - writer.uint32(58).string(message.directory); - } - for (const v of message.apps) { - App.encode(v!, writer.uint32(66).fork()).ldelim(); - } - if (message.token !== undefined) { - writer.uint32(74).string(message.token); - } - if (message.instanceId !== undefined) { - writer.uint32(82).string(message.instanceId); - } - if (message.connectionTimeoutSeconds !== 0) { - writer.uint32(88).int32(message.connectionTimeoutSeconds); - } - if (message.troubleshootingUrl !== "") { - writer.uint32(98).string(message.troubleshootingUrl); - } - if (message.motdFile !== "") { - writer.uint32(106).string(message.motdFile); - } - for (const v of message.metadata) { - Agent_Metadata.encode(v!, writer.uint32(146).fork()).ldelim(); - } - if (message.displayApps !== undefined) { - DisplayApps.encode( - message.displayApps, - writer.uint32(162).fork(), - ).ldelim(); - } - for (const v of message.scripts) { - Script.encode(v!, writer.uint32(170).fork()).ldelim(); - } - for (const v of message.extraEnvs) { - Env.encode(v!, writer.uint32(178).fork()).ldelim(); - } - if (message.order !== 0) { - writer.uint32(184).int64(message.order); - } - return writer; - }, + encode(message: Agent, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.id !== "") { + writer.uint32(10).string(message.id); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + Object.entries(message.env).forEach(([key, value]) => { + Agent_EnvEntry.encode( + { key: key as any, value }, + writer.uint32(26).fork(), + ).ldelim(); + }); + if (message.operatingSystem !== "") { + writer.uint32(42).string(message.operatingSystem); + } + if (message.architecture !== "") { + writer.uint32(50).string(message.architecture); + } + if (message.directory !== "") { + writer.uint32(58).string(message.directory); + } + for (const v of message.apps) { + App.encode(v!, writer.uint32(66).fork()).ldelim(); + } + if (message.token !== undefined) { + writer.uint32(74).string(message.token); + } + if (message.instanceId !== undefined) { + writer.uint32(82).string(message.instanceId); + } + if (message.connectionTimeoutSeconds !== 0) { + writer.uint32(88).int32(message.connectionTimeoutSeconds); + } + if (message.troubleshootingUrl !== "") { + writer.uint32(98).string(message.troubleshootingUrl); + } + if (message.motdFile !== "") { + writer.uint32(106).string(message.motdFile); + } + for (const v of message.metadata) { + Agent_Metadata.encode(v!, writer.uint32(146).fork()).ldelim(); + } + if (message.displayApps !== undefined) { + DisplayApps.encode( + message.displayApps, + writer.uint32(162).fork(), + ).ldelim(); + } + for (const v of message.scripts) { + Script.encode(v!, writer.uint32(170).fork()).ldelim(); + } + for (const v of message.extraEnvs) { + Env.encode(v!, writer.uint32(178).fork()).ldelim(); + } + if (message.order !== 0) { + writer.uint32(184).int64(message.order); + } + return writer; + }, }; export const Agent_Metadata = { - encode( - message: Agent_Metadata, - writer: _m0.Writer = _m0.Writer.create(), - ): _m0.Writer { - if (message.key !== "") { - writer.uint32(10).string(message.key); - } - if (message.displayName !== "") { - writer.uint32(18).string(message.displayName); - } - if (message.script !== "") { - writer.uint32(26).string(message.script); - } - if (message.interval !== 0) { - writer.uint32(32).int64(message.interval); - } - if (message.timeout !== 0) { - writer.uint32(40).int64(message.timeout); - } - if (message.order !== 0) { - writer.uint32(48).int64(message.order); - } - return writer; - }, + encode( + message: Agent_Metadata, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.key !== "") { + writer.uint32(10).string(message.key); + } + if (message.displayName !== "") { + writer.uint32(18).string(message.displayName); + } + if (message.script !== "") { + writer.uint32(26).string(message.script); + } + if (message.interval !== 0) { + writer.uint32(32).int64(message.interval); + } + if (message.timeout !== 0) { + writer.uint32(40).int64(message.timeout); + } + if (message.order !== 0) { + writer.uint32(48).int64(message.order); + } + return writer; + }, }; export const Agent_EnvEntry = { - encode( - message: Agent_EnvEntry, - writer: _m0.Writer = _m0.Writer.create(), - ): _m0.Writer { - if (message.key !== "") { - writer.uint32(10).string(message.key); - } - if (message.value !== "") { - writer.uint32(18).string(message.value); - } - return writer; - }, + encode( + message: Agent_EnvEntry, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.key !== "") { + writer.uint32(10).string(message.key); + } + if (message.value !== "") { + writer.uint32(18).string(message.value); + } + return writer; + }, }; export const DisplayApps = { - encode( - message: DisplayApps, - writer: _m0.Writer = _m0.Writer.create(), - ): _m0.Writer { - if (message.vscode === true) { - writer.uint32(8).bool(message.vscode); - } - if (message.vscodeInsiders === true) { - writer.uint32(16).bool(message.vscodeInsiders); - } - if (message.webTerminal === true) { - writer.uint32(24).bool(message.webTerminal); - } - if (message.sshHelper === true) { - writer.uint32(32).bool(message.sshHelper); - } - if (message.portForwardingHelper === true) { - writer.uint32(40).bool(message.portForwardingHelper); - } - return writer; - }, + encode( + message: DisplayApps, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.vscode === true) { + writer.uint32(8).bool(message.vscode); + } + if (message.vscodeInsiders === true) { + writer.uint32(16).bool(message.vscodeInsiders); + } + if (message.webTerminal === true) { + writer.uint32(24).bool(message.webTerminal); + } + if (message.sshHelper === true) { + writer.uint32(32).bool(message.sshHelper); + } + if (message.portForwardingHelper === true) { + writer.uint32(40).bool(message.portForwardingHelper); + } + return writer; + }, }; export const Env = { - encode(message: Env, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { - if (message.name !== "") { - writer.uint32(10).string(message.name); - } - if (message.value !== "") { - writer.uint32(18).string(message.value); - } - return writer; - }, + encode(message: Env, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.name !== "") { + writer.uint32(10).string(message.name); + } + if (message.value !== "") { + writer.uint32(18).string(message.value); + } + return writer; + }, }; export const Script = { - encode( - message: Script, - writer: _m0.Writer = _m0.Writer.create(), - ): _m0.Writer { - if (message.displayName !== "") { - writer.uint32(10).string(message.displayName); - } - if (message.icon !== "") { - writer.uint32(18).string(message.icon); - } - if (message.script !== "") { - writer.uint32(26).string(message.script); - } - if (message.cron !== "") { - writer.uint32(34).string(message.cron); - } - if (message.startBlocksLogin === true) { - writer.uint32(40).bool(message.startBlocksLogin); - } - if (message.runOnStart === true) { - writer.uint32(48).bool(message.runOnStart); - } - if (message.runOnStop === true) { - writer.uint32(56).bool(message.runOnStop); - } - if (message.timeoutSeconds !== 0) { - writer.uint32(64).int32(message.timeoutSeconds); - } - if (message.logPath !== "") { - writer.uint32(74).string(message.logPath); - } - return writer; - }, + encode( + message: Script, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.displayName !== "") { + writer.uint32(10).string(message.displayName); + } + if (message.icon !== "") { + writer.uint32(18).string(message.icon); + } + if (message.script !== "") { + writer.uint32(26).string(message.script); + } + if (message.cron !== "") { + writer.uint32(34).string(message.cron); + } + if (message.startBlocksLogin === true) { + writer.uint32(40).bool(message.startBlocksLogin); + } + if (message.runOnStart === true) { + writer.uint32(48).bool(message.runOnStart); + } + if (message.runOnStop === true) { + writer.uint32(56).bool(message.runOnStop); + } + if (message.timeoutSeconds !== 0) { + writer.uint32(64).int32(message.timeoutSeconds); + } + if (message.logPath !== "") { + writer.uint32(74).string(message.logPath); + } + return writer; + }, }; export const App = { - encode(message: App, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { - if (message.slug !== "") { - writer.uint32(10).string(message.slug); - } - if (message.displayName !== "") { - writer.uint32(18).string(message.displayName); - } - if (message.command !== "") { - writer.uint32(26).string(message.command); - } - if (message.url !== "") { - writer.uint32(34).string(message.url); - } - if (message.icon !== "") { - writer.uint32(42).string(message.icon); - } - if (message.subdomain === true) { - writer.uint32(48).bool(message.subdomain); - } - if (message.healthcheck !== undefined) { - Healthcheck.encode( - message.healthcheck, - writer.uint32(58).fork(), - ).ldelim(); - } - if (message.sharingLevel !== 0) { - writer.uint32(64).int32(message.sharingLevel); - } - if (message.external === true) { - writer.uint32(72).bool(message.external); - } - if (message.order !== 0) { - writer.uint32(80).int64(message.order); - } - return writer; - }, + encode(message: App, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.slug !== "") { + writer.uint32(10).string(message.slug); + } + if (message.displayName !== "") { + writer.uint32(18).string(message.displayName); + } + if (message.command !== "") { + writer.uint32(26).string(message.command); + } + if (message.url !== "") { + writer.uint32(34).string(message.url); + } + if (message.icon !== "") { + writer.uint32(42).string(message.icon); + } + if (message.subdomain === true) { + writer.uint32(48).bool(message.subdomain); + } + if (message.healthcheck !== undefined) { + Healthcheck.encode( + message.healthcheck, + writer.uint32(58).fork(), + ).ldelim(); + } + if (message.sharingLevel !== 0) { + writer.uint32(64).int32(message.sharingLevel); + } + if (message.external === true) { + writer.uint32(72).bool(message.external); + } + if (message.order !== 0) { + writer.uint32(80).int64(message.order); + } + return writer; + }, }; export const Healthcheck = { - encode( - message: Healthcheck, - writer: _m0.Writer = _m0.Writer.create(), - ): _m0.Writer { - if (message.url !== "") { - writer.uint32(10).string(message.url); - } - if (message.interval !== 0) { - writer.uint32(16).int32(message.interval); - } - if (message.threshold !== 0) { - writer.uint32(24).int32(message.threshold); - } - return writer; - }, + encode( + message: Healthcheck, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.url !== "") { + writer.uint32(10).string(message.url); + } + if (message.interval !== 0) { + writer.uint32(16).int32(message.interval); + } + if (message.threshold !== 0) { + writer.uint32(24).int32(message.threshold); + } + return writer; + }, }; export const Resource = { - encode( - message: Resource, - writer: _m0.Writer = _m0.Writer.create(), - ): _m0.Writer { - if (message.name !== "") { - writer.uint32(10).string(message.name); - } - if (message.type !== "") { - writer.uint32(18).string(message.type); - } - for (const v of message.agents) { - Agent.encode(v!, writer.uint32(26).fork()).ldelim(); - } - for (const v of message.metadata) { - Resource_Metadata.encode(v!, writer.uint32(34).fork()).ldelim(); - } - if (message.hide === true) { - writer.uint32(40).bool(message.hide); - } - if (message.icon !== "") { - writer.uint32(50).string(message.icon); - } - if (message.instanceType !== "") { - writer.uint32(58).string(message.instanceType); - } - if (message.dailyCost !== 0) { - writer.uint32(64).int32(message.dailyCost); - } - return writer; - }, + encode( + message: Resource, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.name !== "") { + writer.uint32(10).string(message.name); + } + if (message.type !== "") { + writer.uint32(18).string(message.type); + } + for (const v of message.agents) { + Agent.encode(v!, writer.uint32(26).fork()).ldelim(); + } + for (const v of message.metadata) { + Resource_Metadata.encode(v!, writer.uint32(34).fork()).ldelim(); + } + if (message.hide === true) { + writer.uint32(40).bool(message.hide); + } + if (message.icon !== "") { + writer.uint32(50).string(message.icon); + } + if (message.instanceType !== "") { + writer.uint32(58).string(message.instanceType); + } + if (message.dailyCost !== 0) { + writer.uint32(64).int32(message.dailyCost); + } + return writer; + }, }; export const Resource_Metadata = { - encode( - message: Resource_Metadata, - writer: _m0.Writer = _m0.Writer.create(), - ): _m0.Writer { - if (message.key !== "") { - writer.uint32(10).string(message.key); - } - if (message.value !== "") { - writer.uint32(18).string(message.value); - } - if (message.sensitive === true) { - writer.uint32(24).bool(message.sensitive); - } - if (message.isNull === true) { - writer.uint32(32).bool(message.isNull); - } - return writer; - }, + encode( + message: Resource_Metadata, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.key !== "") { + writer.uint32(10).string(message.key); + } + if (message.value !== "") { + writer.uint32(18).string(message.value); + } + if (message.sensitive === true) { + writer.uint32(24).bool(message.sensitive); + } + if (message.isNull === true) { + writer.uint32(32).bool(message.isNull); + } + return writer; + }, }; export const Metadata = { - encode( - message: Metadata, - writer: _m0.Writer = _m0.Writer.create(), - ): _m0.Writer { - if (message.coderUrl !== "") { - writer.uint32(10).string(message.coderUrl); - } - if (message.workspaceTransition !== 0) { - writer.uint32(16).int32(message.workspaceTransition); - } - if (message.workspaceName !== "") { - writer.uint32(26).string(message.workspaceName); - } - if (message.workspaceOwner !== "") { - writer.uint32(34).string(message.workspaceOwner); - } - if (message.workspaceId !== "") { - writer.uint32(42).string(message.workspaceId); - } - if (message.workspaceOwnerId !== "") { - writer.uint32(50).string(message.workspaceOwnerId); - } - if (message.workspaceOwnerEmail !== "") { - writer.uint32(58).string(message.workspaceOwnerEmail); - } - if (message.templateName !== "") { - writer.uint32(66).string(message.templateName); - } - if (message.templateVersion !== "") { - writer.uint32(74).string(message.templateVersion); - } - if (message.workspaceOwnerOidcAccessToken !== "") { - writer.uint32(82).string(message.workspaceOwnerOidcAccessToken); - } - if (message.workspaceOwnerSessionToken !== "") { - writer.uint32(90).string(message.workspaceOwnerSessionToken); - } - if (message.templateId !== "") { - writer.uint32(98).string(message.templateId); - } - if (message.workspaceOwnerName !== "") { - writer.uint32(106).string(message.workspaceOwnerName); - } - for (const v of message.workspaceOwnerGroups) { - writer.uint32(114).string(v!); - } - if (message.workspaceOwnerSshPublicKey !== "") { - writer.uint32(122).string(message.workspaceOwnerSshPublicKey); - } - if (message.workspaceOwnerSshPrivateKey !== "") { - writer.uint32(130).string(message.workspaceOwnerSshPrivateKey); - } - if (message.workspaceBuildId !== "") { - writer.uint32(138).string(message.workspaceBuildId); - } - return writer; - }, + encode( + message: Metadata, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.coderUrl !== "") { + writer.uint32(10).string(message.coderUrl); + } + if (message.workspaceTransition !== 0) { + writer.uint32(16).int32(message.workspaceTransition); + } + if (message.workspaceName !== "") { + writer.uint32(26).string(message.workspaceName); + } + if (message.workspaceOwner !== "") { + writer.uint32(34).string(message.workspaceOwner); + } + if (message.workspaceId !== "") { + writer.uint32(42).string(message.workspaceId); + } + if (message.workspaceOwnerId !== "") { + writer.uint32(50).string(message.workspaceOwnerId); + } + if (message.workspaceOwnerEmail !== "") { + writer.uint32(58).string(message.workspaceOwnerEmail); + } + if (message.templateName !== "") { + writer.uint32(66).string(message.templateName); + } + if (message.templateVersion !== "") { + writer.uint32(74).string(message.templateVersion); + } + if (message.workspaceOwnerOidcAccessToken !== "") { + writer.uint32(82).string(message.workspaceOwnerOidcAccessToken); + } + if (message.workspaceOwnerSessionToken !== "") { + writer.uint32(90).string(message.workspaceOwnerSessionToken); + } + if (message.templateId !== "") { + writer.uint32(98).string(message.templateId); + } + if (message.workspaceOwnerName !== "") { + writer.uint32(106).string(message.workspaceOwnerName); + } + for (const v of message.workspaceOwnerGroups) { + writer.uint32(114).string(v!); + } + if (message.workspaceOwnerSshPublicKey !== "") { + writer.uint32(122).string(message.workspaceOwnerSshPublicKey); + } + if (message.workspaceOwnerSshPrivateKey !== "") { + writer.uint32(130).string(message.workspaceOwnerSshPrivateKey); + } + if (message.workspaceBuildId !== "") { + writer.uint32(138).string(message.workspaceBuildId); + } + return writer; + }, }; export const Config = { - encode( - message: Config, - writer: _m0.Writer = _m0.Writer.create(), - ): _m0.Writer { - if (message.templateSourceArchive.length !== 0) { - writer.uint32(10).bytes(message.templateSourceArchive); - } - if (message.state.length !== 0) { - writer.uint32(18).bytes(message.state); - } - if (message.provisionerLogLevel !== "") { - writer.uint32(26).string(message.provisionerLogLevel); - } - return writer; - }, + encode( + message: Config, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.templateSourceArchive.length !== 0) { + writer.uint32(10).bytes(message.templateSourceArchive); + } + if (message.state.length !== 0) { + writer.uint32(18).bytes(message.state); + } + if (message.provisionerLogLevel !== "") { + writer.uint32(26).string(message.provisionerLogLevel); + } + return writer; + }, }; export const ParseRequest = { - encode( - _: ParseRequest, - writer: _m0.Writer = _m0.Writer.create(), - ): _m0.Writer { - return writer; - }, + encode( + _: ParseRequest, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + return writer; + }, }; export const ParseComplete = { - encode( - message: ParseComplete, - writer: _m0.Writer = _m0.Writer.create(), - ): _m0.Writer { - if (message.error !== "") { - writer.uint32(10).string(message.error); - } - for (const v of message.templateVariables) { - TemplateVariable.encode(v!, writer.uint32(18).fork()).ldelim(); - } - if (message.readme.length !== 0) { - writer.uint32(26).bytes(message.readme); - } - Object.entries(message.workspaceTags).forEach(([key, value]) => { - ParseComplete_WorkspaceTagsEntry.encode( - { key: key as any, value }, - writer.uint32(34).fork(), - ).ldelim(); - }); - return writer; - }, + encode( + message: ParseComplete, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.error !== "") { + writer.uint32(10).string(message.error); + } + for (const v of message.templateVariables) { + TemplateVariable.encode(v!, writer.uint32(18).fork()).ldelim(); + } + if (message.readme.length !== 0) { + writer.uint32(26).bytes(message.readme); + } + Object.entries(message.workspaceTags).forEach(([key, value]) => { + ParseComplete_WorkspaceTagsEntry.encode( + { key: key as any, value }, + writer.uint32(34).fork(), + ).ldelim(); + }); + return writer; + }, }; export const ParseComplete_WorkspaceTagsEntry = { - encode( - message: ParseComplete_WorkspaceTagsEntry, - writer: _m0.Writer = _m0.Writer.create(), - ): _m0.Writer { - if (message.key !== "") { - writer.uint32(10).string(message.key); - } - if (message.value !== "") { - writer.uint32(18).string(message.value); - } - return writer; - }, + encode( + message: ParseComplete_WorkspaceTagsEntry, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.key !== "") { + writer.uint32(10).string(message.key); + } + if (message.value !== "") { + writer.uint32(18).string(message.value); + } + return writer; + }, }; export const PlanRequest = { - encode( - message: PlanRequest, - writer: _m0.Writer = _m0.Writer.create(), - ): _m0.Writer { - if (message.metadata !== undefined) { - Metadata.encode(message.metadata, writer.uint32(10).fork()).ldelim(); - } - for (const v of message.richParameterValues) { - RichParameterValue.encode(v!, writer.uint32(18).fork()).ldelim(); - } - for (const v of message.variableValues) { - VariableValue.encode(v!, writer.uint32(26).fork()).ldelim(); - } - for (const v of message.externalAuthProviders) { - ExternalAuthProvider.encode(v!, writer.uint32(34).fork()).ldelim(); - } - return writer; - }, + encode( + message: PlanRequest, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.metadata !== undefined) { + Metadata.encode(message.metadata, writer.uint32(10).fork()).ldelim(); + } + for (const v of message.richParameterValues) { + RichParameterValue.encode(v!, writer.uint32(18).fork()).ldelim(); + } + for (const v of message.variableValues) { + VariableValue.encode(v!, writer.uint32(26).fork()).ldelim(); + } + for (const v of message.externalAuthProviders) { + ExternalAuthProvider.encode(v!, writer.uint32(34).fork()).ldelim(); + } + return writer; + }, }; export const PlanComplete = { - encode( - message: PlanComplete, - writer: _m0.Writer = _m0.Writer.create(), - ): _m0.Writer { - if (message.error !== "") { - writer.uint32(10).string(message.error); - } - for (const v of message.resources) { - Resource.encode(v!, writer.uint32(18).fork()).ldelim(); - } - for (const v of message.parameters) { - RichParameter.encode(v!, writer.uint32(26).fork()).ldelim(); - } - for (const v of message.externalAuthProviders) { - ExternalAuthProviderResource.encode( - v!, - writer.uint32(34).fork(), - ).ldelim(); - } - return writer; - }, + encode( + message: PlanComplete, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.error !== "") { + writer.uint32(10).string(message.error); + } + for (const v of message.resources) { + Resource.encode(v!, writer.uint32(18).fork()).ldelim(); + } + for (const v of message.parameters) { + RichParameter.encode(v!, writer.uint32(26).fork()).ldelim(); + } + for (const v of message.externalAuthProviders) { + ExternalAuthProviderResource.encode( + v!, + writer.uint32(34).fork(), + ).ldelim(); + } + return writer; + }, }; export const ApplyRequest = { - encode( - message: ApplyRequest, - writer: _m0.Writer = _m0.Writer.create(), - ): _m0.Writer { - if (message.metadata !== undefined) { - Metadata.encode(message.metadata, writer.uint32(10).fork()).ldelim(); - } - return writer; - }, + encode( + message: ApplyRequest, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.metadata !== undefined) { + Metadata.encode(message.metadata, writer.uint32(10).fork()).ldelim(); + } + return writer; + }, }; export const ApplyComplete = { - encode( - message: ApplyComplete, - writer: _m0.Writer = _m0.Writer.create(), - ): _m0.Writer { - if (message.state.length !== 0) { - writer.uint32(10).bytes(message.state); - } - if (message.error !== "") { - writer.uint32(18).string(message.error); - } - for (const v of message.resources) { - Resource.encode(v!, writer.uint32(26).fork()).ldelim(); - } - for (const v of message.parameters) { - RichParameter.encode(v!, writer.uint32(34).fork()).ldelim(); - } - for (const v of message.externalAuthProviders) { - ExternalAuthProviderResource.encode( - v!, - writer.uint32(42).fork(), - ).ldelim(); - } - return writer; - }, + encode( + message: ApplyComplete, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.state.length !== 0) { + writer.uint32(10).bytes(message.state); + } + if (message.error !== "") { + writer.uint32(18).string(message.error); + } + for (const v of message.resources) { + Resource.encode(v!, writer.uint32(26).fork()).ldelim(); + } + for (const v of message.parameters) { + RichParameter.encode(v!, writer.uint32(34).fork()).ldelim(); + } + for (const v of message.externalAuthProviders) { + ExternalAuthProviderResource.encode( + v!, + writer.uint32(42).fork(), + ).ldelim(); + } + return writer; + }, }; export const CancelRequest = { - encode( - _: CancelRequest, - writer: _m0.Writer = _m0.Writer.create(), - ): _m0.Writer { - return writer; - }, + encode( + _: CancelRequest, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + return writer; + }, }; export const Request = { - encode( - message: Request, - writer: _m0.Writer = _m0.Writer.create(), - ): _m0.Writer { - if (message.config !== undefined) { - Config.encode(message.config, writer.uint32(10).fork()).ldelim(); - } - if (message.parse !== undefined) { - ParseRequest.encode(message.parse, writer.uint32(18).fork()).ldelim(); - } - if (message.plan !== undefined) { - PlanRequest.encode(message.plan, writer.uint32(26).fork()).ldelim(); - } - if (message.apply !== undefined) { - ApplyRequest.encode(message.apply, writer.uint32(34).fork()).ldelim(); - } - if (message.cancel !== undefined) { - CancelRequest.encode(message.cancel, writer.uint32(42).fork()).ldelim(); - } - return writer; - }, + encode( + message: Request, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.config !== undefined) { + Config.encode(message.config, writer.uint32(10).fork()).ldelim(); + } + if (message.parse !== undefined) { + ParseRequest.encode(message.parse, writer.uint32(18).fork()).ldelim(); + } + if (message.plan !== undefined) { + PlanRequest.encode(message.plan, writer.uint32(26).fork()).ldelim(); + } + if (message.apply !== undefined) { + ApplyRequest.encode(message.apply, writer.uint32(34).fork()).ldelim(); + } + if (message.cancel !== undefined) { + CancelRequest.encode(message.cancel, writer.uint32(42).fork()).ldelim(); + } + return writer; + }, }; export const Response = { - encode( - message: Response, - writer: _m0.Writer = _m0.Writer.create(), - ): _m0.Writer { - if (message.log !== undefined) { - Log.encode(message.log, writer.uint32(10).fork()).ldelim(); - } - if (message.parse !== undefined) { - ParseComplete.encode(message.parse, writer.uint32(18).fork()).ldelim(); - } - if (message.plan !== undefined) { - PlanComplete.encode(message.plan, writer.uint32(26).fork()).ldelim(); - } - if (message.apply !== undefined) { - ApplyComplete.encode(message.apply, writer.uint32(34).fork()).ldelim(); - } - return writer; - }, + encode( + message: Response, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.log !== undefined) { + Log.encode(message.log, writer.uint32(10).fork()).ldelim(); + } + if (message.parse !== undefined) { + ParseComplete.encode(message.parse, writer.uint32(18).fork()).ldelim(); + } + if (message.plan !== undefined) { + PlanComplete.encode(message.plan, writer.uint32(26).fork()).ldelim(); + } + if (message.apply !== undefined) { + ApplyComplete.encode(message.apply, writer.uint32(34).fork()).ldelim(); + } + return writer; + }, }; export interface Provisioner { - /** - * Session represents provisioning a single template import or workspace. The daemon always sends Config followed - * by one of the requests (ParseRequest, PlanRequest, ApplyRequest). The provisioner should respond with a stream - * of zero or more Logs, followed by the corresponding complete message (ParseComplete, PlanComplete, - * ApplyComplete). The daemon may then send a new request. A request to apply MUST be preceded by a request plan, - * and the provisioner should store the plan data on the Session after a successful plan, so that the daemon may - * request an apply. If the daemon closes the Session without an apply, the plan data may be safely discarded. - * - * The daemon may send a CancelRequest, asynchronously to ask the provisioner to cancel the previous ParseRequest, - * PlanRequest, or ApplyRequest. The provisioner MUST reply with a complete message corresponding to the request - * that was canceled. If the provisioner has already completed the request, it may ignore the CancelRequest. - */ - Session(request: Observable): Observable; + /** + * Session represents provisioning a single template import or workspace. The daemon always sends Config followed + * by one of the requests (ParseRequest, PlanRequest, ApplyRequest). The provisioner should respond with a stream + * of zero or more Logs, followed by the corresponding complete message (ParseComplete, PlanComplete, + * ApplyComplete). The daemon may then send a new request. A request to apply MUST be preceded by a request plan, + * and the provisioner should store the plan data on the Session after a successful plan, so that the daemon may + * request an apply. If the daemon closes the Session without an apply, the plan data may be safely discarded. + * + * The daemon may send a CancelRequest, asynchronously to ask the provisioner to cancel the previous ParseRequest, + * PlanRequest, or ApplyRequest. The provisioner MUST reply with a complete message corresponding to the request + * that was canceled. If the provisioner has already completed the request, it may ignore the CancelRequest. + */ + Session(request: Observable): Observable; } diff --git a/site/e2e/proxy.ts b/site/e2e/proxy.ts index c3f9d9ee1f..29089cdd75 100644 --- a/site/e2e/proxy.ts +++ b/site/e2e/proxy.ts @@ -3,36 +3,36 @@ import { coderMain, coderPort, workspaceProxyPort } from "./constants"; import { waitUntilUrlIsNotResponding } from "./helpers"; export const startWorkspaceProxy = async ( - token: string, + token: string, ): Promise => { - const cp = spawn("go", ["run", coderMain, "wsproxy", "server"], { - env: { - ...process.env, - CODER_PRIMARY_ACCESS_URL: `http://127.0.0.1:${coderPort}`, - CODER_PROXY_SESSION_TOKEN: token, - CODER_HTTP_ADDRESS: `localhost:${workspaceProxyPort}`, - }, - }); - cp.stdout.on("data", (data: Buffer) => { - // eslint-disable-next-line no-console -- Log wsproxy activity - console.log( - `[wsproxy] [stdout] [onData] ${data.toString().replace(/\n$/g, "")}`, - ); - }); - cp.stderr.on("data", (data: Buffer) => { - // eslint-disable-next-line no-console -- Log wsproxy activity - console.log( - `[wsproxy] [stderr] [onData] ${data.toString().replace(/\n$/g, "")}`, - ); - }); - return cp; + const cp = spawn("go", ["run", coderMain, "wsproxy", "server"], { + env: { + ...process.env, + CODER_PRIMARY_ACCESS_URL: `http://127.0.0.1:${coderPort}`, + CODER_PROXY_SESSION_TOKEN: token, + CODER_HTTP_ADDRESS: `localhost:${workspaceProxyPort}`, + }, + }); + cp.stdout.on("data", (data: Buffer) => { + // eslint-disable-next-line no-console -- Log wsproxy activity + console.log( + `[wsproxy] [stdout] [onData] ${data.toString().replace(/\n$/g, "")}`, + ); + }); + cp.stderr.on("data", (data: Buffer) => { + // eslint-disable-next-line no-console -- Log wsproxy activity + console.log( + `[wsproxy] [stderr] [onData] ${data.toString().replace(/\n$/g, "")}`, + ); + }); + return cp; }; export const stopWorkspaceProxy = async (cp: ChildProcess, goRun = true) => { - exec(goRun ? `pkill -P ${cp.pid}` : `kill ${cp.pid}`, (error) => { - if (error) { - throw new Error(`exec error: ${JSON.stringify(error)}`); - } - }); - await waitUntilUrlIsNotResponding(`http://127.0.0.1:${workspaceProxyPort}`); + exec(goRun ? `pkill -P ${cp.pid}` : `kill ${cp.pid}`, (error) => { + if (error) { + throw new Error(`exec error: ${JSON.stringify(error)}`); + } + }); + await waitUntilUrlIsNotResponding(`http://127.0.0.1:${workspaceProxyPort}`); }; diff --git a/site/e2e/reporter.ts b/site/e2e/reporter.ts index 142597fc3b..21d67aa980 100644 --- a/site/e2e/reporter.ts +++ b/site/e2e/reporter.ts @@ -2,172 +2,172 @@ import * as fs from "node:fs/promises"; import type { Writable } from "node:stream"; /* eslint-disable no-console -- Logging is sort of the whole point here */ import type { - FullConfig, - FullResult, - Reporter, - Suite, - TestCase, - TestError, - TestResult, + FullConfig, + FullResult, + Reporter, + Suite, + TestCase, + TestError, + TestResult, } from "@playwright/test/reporter"; import { API } from "api/api"; import { coderdPProfPort, enterpriseLicense } from "./constants"; class CoderReporter implements Reporter { - config: FullConfig | null = null; - testOutput = new Map>(); - passedCount = 0; - skippedCount = 0; - failedTests: TestCase[] = []; - timedOutTests: TestCase[] = []; + config: FullConfig | null = null; + testOutput = new Map>(); + passedCount = 0; + skippedCount = 0; + failedTests: TestCase[] = []; + timedOutTests: TestCase[] = []; - onBegin(config: FullConfig, suite: Suite) { - this.config = config; - console.log(`==> Running ${suite.allTests().length} tests`); - } + onBegin(config: FullConfig, suite: Suite) { + this.config = config; + console.log(`==> Running ${suite.allTests().length} tests`); + } - onTestBegin(test: TestCase) { - this.testOutput.set(test.id, []); - console.log(`==> Starting test ${test.title}`); - } + onTestBegin(test: TestCase) { + this.testOutput.set(test.id, []); + console.log(`==> Starting test ${test.title}`); + } - onStdOut(chunk: string, test?: TestCase, _?: TestResult): void { - // If there's no associated test, just print it now - if (!test) { - for (const line of logLines(chunk)) { - console.log(`[stdout] ${line}`); - } - return; - } - // Will be printed if the test fails - this.testOutput.get(test.id)!.push([process.stdout, chunk]); - } + onStdOut(chunk: string, test?: TestCase, _?: TestResult): void { + // If there's no associated test, just print it now + if (!test) { + for (const line of logLines(chunk)) { + console.log(`[stdout] ${line}`); + } + return; + } + // Will be printed if the test fails + this.testOutput.get(test.id)!.push([process.stdout, chunk]); + } - onStdErr(chunk: string, test?: TestCase, _?: TestResult): void { - // If there's no associated test, just print it now - if (!test) { - for (const line of logLines(chunk)) { - console.error(`[stderr] ${line}`); - } - return; - } - // Will be printed if the test fails - this.testOutput.get(test.id)!.push([process.stderr, chunk]); - } + onStdErr(chunk: string, test?: TestCase, _?: TestResult): void { + // If there's no associated test, just print it now + if (!test) { + for (const line of logLines(chunk)) { + console.error(`[stderr] ${line}`); + } + return; + } + // Will be printed if the test fails + this.testOutput.get(test.id)!.push([process.stderr, chunk]); + } - async onTestEnd(test: TestCase, result: TestResult) { - try { - if (test.expectedStatus === "skipped") { - console.log(`==> Skipping test ${test.title}`); - this.skippedCount++; - return; - } + async onTestEnd(test: TestCase, result: TestResult) { + try { + if (test.expectedStatus === "skipped") { + console.log(`==> Skipping test ${test.title}`); + this.skippedCount++; + return; + } - console.log(`==> Finished test ${test.title}: ${result.status}`); + console.log(`==> Finished test ${test.title}: ${result.status}`); - if (result.status === "passed") { - this.passedCount++; - return; - } + if (result.status === "passed") { + this.passedCount++; + return; + } - if (result.status === "failed") { - this.failedTests.push(test); - } + if (result.status === "failed") { + this.failedTests.push(test); + } - if (result.status === "timedOut") { - this.timedOutTests.push(test); - } + if (result.status === "timedOut") { + this.timedOutTests.push(test); + } - const fsTestTitle = test.title.replaceAll(" ", "-"); - const outputFile = `test-results/debug-pprof-goroutine-${fsTestTitle}.txt`; - await exportDebugPprof(outputFile); + const fsTestTitle = test.title.replaceAll(" ", "-"); + const outputFile = `test-results/debug-pprof-goroutine-${fsTestTitle}.txt`; + await exportDebugPprof(outputFile); - console.log(`Data from pprof has been saved to ${outputFile}`); - console.log("==> Output"); - const output = this.testOutput.get(test.id)!; - for (const [target, chunk] of output) { - target.write(`${chunk.replace(/\n$/g, "")}\n`); - } + console.log(`Data from pprof has been saved to ${outputFile}`); + console.log("==> Output"); + const output = this.testOutput.get(test.id)!; + for (const [target, chunk] of output) { + target.write(`${chunk.replace(/\n$/g, "")}\n`); + } - if (result.errors.length > 0) { - console.log("==> Errors"); - for (const error of result.errors) { - reportError(error); - } - } + if (result.errors.length > 0) { + console.log("==> Errors"); + for (const error of result.errors) { + reportError(error); + } + } - if (result.attachments.length > 0) { - console.log("==> Attachments"); - for (const attachment of result.attachments) { - console.log(attachment); - } - } - } finally { - this.testOutput.delete(test.id); - } - } + if (result.attachments.length > 0) { + console.log("==> Attachments"); + for (const attachment of result.attachments) { + console.log(attachment); + } + } + } finally { + this.testOutput.delete(test.id); + } + } - onEnd(result: FullResult) { - console.log(`==> Tests ${result.status}`); - if (!enterpriseLicense) { - console.log( - "==> Enterprise tests were skipped, because no license was provided", - ); - } - console.log(`${this.passedCount} passed`); - if (this.skippedCount > 0) { - console.log(`${this.skippedCount} skipped`); - } - if (this.failedTests.length > 0) { - console.log(`${this.failedTests.length} failed`); - for (const test of this.failedTests) { - console.log(` ${test.location.file} › ${test.title}`); - } - } - if (this.timedOutTests.length > 0) { - console.log(`${this.timedOutTests.length} timed out`); - for (const test of this.timedOutTests) { - console.log(` ${test.location.file} › ${test.title}`); - } - } - } + onEnd(result: FullResult) { + console.log(`==> Tests ${result.status}`); + if (!enterpriseLicense) { + console.log( + "==> Enterprise tests were skipped, because no license was provided", + ); + } + console.log(`${this.passedCount} passed`); + if (this.skippedCount > 0) { + console.log(`${this.skippedCount} skipped`); + } + if (this.failedTests.length > 0) { + console.log(`${this.failedTests.length} failed`); + for (const test of this.failedTests) { + console.log(` ${test.location.file} › ${test.title}`); + } + } + if (this.timedOutTests.length > 0) { + console.log(`${this.timedOutTests.length} timed out`); + for (const test of this.timedOutTests) { + console.log(` ${test.location.file} › ${test.title}`); + } + } + } } const logLines = (chunk: string | Buffer): string[] => { - if (chunk instanceof Buffer) { - // When running in a debugger, the input to this is a Buffer instead of a string. - // Unsure why, but this prevents the `trimEnd` from throwing an error. - return [chunk.toString()]; - } - return chunk.trimEnd().split("\n"); + if (chunk instanceof Buffer) { + // When running in a debugger, the input to this is a Buffer instead of a string. + // Unsure why, but this prevents the `trimEnd` from throwing an error. + return [chunk.toString()]; + } + return chunk.trimEnd().split("\n"); }; const exportDebugPprof = async (outputFile: string) => { - const axiosInstance = API.getAxiosInstance(); - const response = await axiosInstance.get( - `http://127.0.0.1:${coderdPProfPort}/debug/pprof/goroutine?debug=1`, - ); + const axiosInstance = API.getAxiosInstance(); + const response = await axiosInstance.get( + `http://127.0.0.1:${coderdPProfPort}/debug/pprof/goroutine?debug=1`, + ); - if (response.status !== 200) { - throw new Error(`Error: Received status code ${response.status}`); - } + if (response.status !== 200) { + throw new Error(`Error: Received status code ${response.status}`); + } - await fs.writeFile(outputFile, response.data); + await fs.writeFile(outputFile, response.data); }; const reportError = (error: TestError) => { - if (error.location) { - console.log(`${error.location.file}:${error.location.line}:`); - } - if (error.snippet) { - console.log(error.snippet); - } + if (error.location) { + console.log(`${error.location.file}:${error.location.line}:`); + } + if (error.snippet) { + console.log(error.snippet); + } - if (error.message) { - console.log(error.message); - } else { - console.log(error); - } + if (error.message) { + console.log(error.message); + } else { + console.log(error); + } }; // eslint-disable-next-line no-unused-vars -- Playwright config uses it diff --git a/site/e2e/tests/app.spec.ts b/site/e2e/tests/app.spec.ts index 6ed5ed177a..bf127ce9f2 100644 --- a/site/e2e/tests/app.spec.ts +++ b/site/e2e/tests/app.spec.ts @@ -2,65 +2,65 @@ import { randomUUID } from "node:crypto"; import * as http from "node:http"; import { test } from "@playwright/test"; import { - createTemplate, - createWorkspace, - startAgent, - stopAgent, - stopWorkspace, + createTemplate, + createWorkspace, + startAgent, + stopAgent, + stopWorkspace, } from "../helpers"; import { beforeCoderTest } from "../hooks"; test.beforeEach(({ page }) => beforeCoderTest(page)); test("app", async ({ context, page }) => { - const appContent = "Hello World"; - const token = randomUUID(); - const srv = http - .createServer((req, res) => { - res.writeHead(200, { "Content-Type": "text/plain" }); - res.end(appContent); - }) - .listen(0); - const addr = srv.address(); - if (typeof addr !== "object" || !addr) { - throw new Error("Expected addr to be an object"); - } - const appName = "test-app"; - const template = await createTemplate(page, { - apply: [ - { - apply: { - resources: [ - { - agents: [ - { - token, - apps: [ - { - url: `http://localhost:${addr.port}`, - displayName: appName, - order: 0, - }, - ], - order: 0, - }, - ], - }, - ], - }, - }, - ], - }); - const workspaceName = await createWorkspace(page, template); - const agent = await startAgent(page, token); + const appContent = "Hello World"; + const token = randomUUID(); + const srv = http + .createServer((req, res) => { + res.writeHead(200, { "Content-Type": "text/plain" }); + res.end(appContent); + }) + .listen(0); + const addr = srv.address(); + if (typeof addr !== "object" || !addr) { + throw new Error("Expected addr to be an object"); + } + const appName = "test-app"; + const template = await createTemplate(page, { + apply: [ + { + apply: { + resources: [ + { + agents: [ + { + token, + apps: [ + { + url: `http://localhost:${addr.port}`, + displayName: appName, + order: 0, + }, + ], + order: 0, + }, + ], + }, + ], + }, + }, + ], + }); + const workspaceName = await createWorkspace(page, template); + const agent = await startAgent(page, token); - // Wait for the web terminal to open in a new tab - const pagePromise = context.waitForEvent("page"); - await page.getByText(appName).click(); - const app = await pagePromise; - await app.waitForLoadState("domcontentloaded"); - await app.getByText(appContent).isVisible(); + // Wait for the web terminal to open in a new tab + const pagePromise = context.waitForEvent("page"); + await page.getByText(appName).click(); + const app = await pagePromise; + await app.waitForLoadState("domcontentloaded"); + await app.getByText(appContent).isVisible(); - await stopWorkspace(page, workspaceName); - await stopAgent(agent); + await stopWorkspace(page, workspaceName); + await stopAgent(agent); }); diff --git a/site/e2e/tests/auditLogs.spec.ts b/site/e2e/tests/auditLogs.spec.ts index d198a957e1..4b934dbca4 100644 --- a/site/e2e/tests/auditLogs.spec.ts +++ b/site/e2e/tests/auditLogs.spec.ts @@ -1,69 +1,69 @@ import { expect, test } from "@playwright/test"; import { - createTemplate, - createWorkspace, - requiresEnterpriseLicense, + createTemplate, + createWorkspace, + requiresEnterpriseLicense, } from "../helpers"; import { beforeCoderTest } from "../hooks"; test.beforeEach(({ page }) => beforeCoderTest(page)); test("inspecting and filtering audit logs", async ({ page }) => { - requiresEnterpriseLicense(); + requiresEnterpriseLicense(); - const userName = "admin"; - // Do some stuff that should show up in the audit logs - const templateName = await createTemplate(page); - const workspaceName = await createWorkspace(page, templateName); + const userName = "admin"; + // Do some stuff that should show up in the audit logs + const templateName = await createTemplate(page); + const workspaceName = await createWorkspace(page, templateName); - // Go to the audit history - await page.goto("/audit"); + // Go to the audit history + await page.goto("/audit"); - // Make sure those things we did all actually show up - await expect(page.getByText(`${userName} logged in`)).toBeVisible(); - await expect( - page.getByText(`${userName} created template ${templateName}`), - ).toBeVisible(); - await expect( - page.getByText(`${userName} created workspace ${workspaceName}`), - ).toBeVisible(); - await expect( - page.getByText(`${userName} started workspace ${workspaceName}`), - ).toBeVisible(); + // Make sure those things we did all actually show up + await expect(page.getByText(`${userName} logged in`)).toBeVisible(); + await expect( + page.getByText(`${userName} created template ${templateName}`), + ).toBeVisible(); + await expect( + page.getByText(`${userName} created workspace ${workspaceName}`), + ).toBeVisible(); + await expect( + page.getByText(`${userName} started workspace ${workspaceName}`), + ).toBeVisible(); - // Make sure we can inspect the details of the log item - const createdWorkspace = page.locator(".MuiTableRow-root", { - hasText: `${userName} created workspace ${workspaceName}`, - }); - await createdWorkspace.getByLabel("open-dropdown").click(); - await expect( - createdWorkspace.getByText(`automatic_updates: "never"`), - ).toBeVisible(); - await expect( - createdWorkspace.getByText(`name: "${workspaceName}"`), - ).toBeVisible(); + // Make sure we can inspect the details of the log item + const createdWorkspace = page.locator(".MuiTableRow-root", { + hasText: `${userName} created workspace ${workspaceName}`, + }); + await createdWorkspace.getByLabel("open-dropdown").click(); + await expect( + createdWorkspace.getByText(`automatic_updates: "never"`), + ).toBeVisible(); + await expect( + createdWorkspace.getByText(`name: "${workspaceName}"`), + ).toBeVisible(); - const startedWorkspaceMessage = `${userName} started workspace ${workspaceName}`; - const loginMessage = `${userName} logged in`; + const startedWorkspaceMessage = `${userName} started workspace ${workspaceName}`; + const loginMessage = `${userName} logged in`; - // Filter by resource type - await page.getByText("All resource types").click(); - await page.getByRole("menu").getByText("Workspace Build").click(); - // Our workspace build should be visible - await expect(page.getByText(startedWorkspaceMessage)).toBeVisible(); - // Logins should no longer be visible - await expect(page.getByText(loginMessage)).not.toBeVisible(); + // Filter by resource type + await page.getByText("All resource types").click(); + await page.getByRole("menu").getByText("Workspace Build").click(); + // Our workspace build should be visible + await expect(page.getByText(startedWorkspaceMessage)).toBeVisible(); + // Logins should no longer be visible + await expect(page.getByText(loginMessage)).not.toBeVisible(); - // Clear filters, everything should be visible again - await page.getByLabel("Clear filter").click(); - await expect(page.getByText(startedWorkspaceMessage)).toBeVisible(); - await expect(page.getByText(loginMessage)).toBeVisible(); + // Clear filters, everything should be visible again + await page.getByLabel("Clear filter").click(); + await expect(page.getByText(startedWorkspaceMessage)).toBeVisible(); + await expect(page.getByText(loginMessage)).toBeVisible(); - // Filter by action type - await page.getByText("All actions").click(); - await page.getByRole("menu").getByText("Login").click(); - // Logins should be visible - await expect(page.getByText(loginMessage)).toBeVisible(); - // Our workspace build should no longer be visible - await expect(page.getByText(startedWorkspaceMessage)).not.toBeVisible(); + // Filter by action type + await page.getByText("All actions").click(); + await page.getByRole("menu").getByText("Login").click(); + // Logins should be visible + await expect(page.getByText(loginMessage)).toBeVisible(); + // Our workspace build should no longer be visible + await expect(page.getByText(startedWorkspaceMessage)).not.toBeVisible(); }); diff --git a/site/e2e/tests/deployment/appearance.spec.ts b/site/e2e/tests/deployment/appearance.spec.ts index 14aeafe750..e17b26a474 100644 --- a/site/e2e/tests/deployment/appearance.spec.ts +++ b/site/e2e/tests/deployment/appearance.spec.ts @@ -3,80 +3,80 @@ import { expectUrl } from "../../expectUrl"; import { randomName, requiresEnterpriseLicense } from "../../helpers"; test("set application name", async ({ page }) => { - requiresEnterpriseLicense(); + requiresEnterpriseLicense(); - await page.goto("/deployment/appearance", { waitUntil: "domcontentloaded" }); + await page.goto("/deployment/appearance", { waitUntil: "domcontentloaded" }); - const applicationName = randomName(); + const applicationName = randomName(); - // Fill out the form - const form = page.locator("form", { hasText: "Application name" }); - await form - .getByLabel("Application name", { exact: true }) - .fill(applicationName); - await form.getByRole("button", { name: "Submit" }).click(); + // Fill out the form + const form = page.locator("form", { hasText: "Application name" }); + await form + .getByLabel("Application name", { exact: true }) + .fill(applicationName); + await form.getByRole("button", { name: "Submit" }).click(); - // Open a new session without cookies to see the login page - const browser = await chromium.launch(); - const incognitoContext = await browser.newContext(); - await incognitoContext.clearCookies(); - const incognitoPage = await incognitoContext.newPage(); - await incognitoPage.goto("/", { waitUntil: "domcontentloaded" }); + // Open a new session without cookies to see the login page + const browser = await chromium.launch(); + const incognitoContext = await browser.newContext(); + await incognitoContext.clearCookies(); + const incognitoPage = await incognitoContext.newPage(); + await incognitoPage.goto("/", { waitUntil: "domcontentloaded" }); - // Verify the application name - const name = incognitoPage.locator("h1", { hasText: applicationName }); - await expect(name).toBeVisible(); + // Verify the application name + const name = incognitoPage.locator("h1", { hasText: applicationName }); + await expect(name).toBeVisible(); - // Shut down browser - await incognitoPage.close(); - await browser.close(); + // Shut down browser + await incognitoPage.close(); + await browser.close(); }); test("set application logo", async ({ page }) => { - requiresEnterpriseLicense(); + requiresEnterpriseLicense(); - await page.goto("/deployment/appearance", { waitUntil: "domcontentloaded" }); + await page.goto("/deployment/appearance", { waitUntil: "domcontentloaded" }); - const imageLink = "/icon/azure.png"; + const imageLink = "/icon/azure.png"; - // Fill out the form - const form = page.locator("form", { hasText: "Logo URL" }); - await form.getByLabel("Logo URL", { exact: true }).fill(imageLink); - await form.getByRole("button", { name: "Submit" }).click(); + // Fill out the form + const form = page.locator("form", { hasText: "Logo URL" }); + await form.getByLabel("Logo URL", { exact: true }).fill(imageLink); + await form.getByRole("button", { name: "Submit" }).click(); - // Open a new session without cookies to see the login page - const browser = await chromium.launch(); - const incognitoContext = await browser.newContext(); - await incognitoContext.clearCookies(); - const incognitoPage = await incognitoContext.newPage(); - await incognitoPage.goto("/", { waitUntil: "domcontentloaded" }); + // Open a new session without cookies to see the login page + const browser = await chromium.launch(); + const incognitoContext = await browser.newContext(); + await incognitoContext.clearCookies(); + const incognitoPage = await incognitoContext.newPage(); + await incognitoPage.goto("/", { waitUntil: "domcontentloaded" }); - // Verify banner - const logo = incognitoPage.locator("img.application-logo"); - await expect(logo).toHaveAttribute("src", imageLink); + // Verify banner + const logo = incognitoPage.locator("img.application-logo"); + await expect(logo).toHaveAttribute("src", imageLink); - // Shut down browser - await incognitoPage.close(); - await browser.close(); + // Shut down browser + await incognitoPage.close(); + await browser.close(); }); test("set service banner", async ({ page }) => { - requiresEnterpriseLicense(); + requiresEnterpriseLicense(); - await page.goto("/deployment/appearance", { waitUntil: "domcontentloaded" }); + await page.goto("/deployment/appearance", { waitUntil: "domcontentloaded" }); - const message = "Mary has a little lamb."; + const message = "Mary has a little lamb."; - // Fill out the form - const form = page.locator("form", { hasText: "Service Banner" }); - await form.getByLabel("Enabled", { exact: true }).check(); - await form.getByLabel("Message", { exact: true }).fill(message); - await form.getByRole("button", { name: "Submit" }).click(); + // Fill out the form + const form = page.locator("form", { hasText: "Service Banner" }); + await form.getByLabel("Enabled", { exact: true }).check(); + await form.getByLabel("Message", { exact: true }).fill(message); + await form.getByRole("button", { name: "Submit" }).click(); - // Verify service banner - await page.goto("/workspaces", { waitUntil: "domcontentloaded" }); - await expectUrl(page).toHavePathName("/workspaces"); + // Verify service banner + await page.goto("/workspaces", { waitUntil: "domcontentloaded" }); + await expectUrl(page).toHavePathName("/workspaces"); - const bar = page.locator("div.service-banner", { hasText: message }); - await expect(bar).toBeVisible(); + const bar = page.locator("div.service-banner", { hasText: message }); + await expect(bar).toBeVisible(); }); diff --git a/site/e2e/tests/deployment/general.spec.ts b/site/e2e/tests/deployment/general.spec.ts index 47e9a22e1a..e4aa5fa1fe 100644 --- a/site/e2e/tests/deployment/general.spec.ts +++ b/site/e2e/tests/deployment/general.spec.ts @@ -4,36 +4,36 @@ import { setupApiCalls } from "../../api"; import { e2eFakeExperiment1, e2eFakeExperiment2 } from "../../constants"; test("experiments", async ({ page }) => { - await setupApiCalls(page); + await setupApiCalls(page); - // Load experiments from backend API - const availableExperiments = await API.getAvailableExperiments(); + // Load experiments from backend API + const availableExperiments = await API.getAvailableExperiments(); - // Verify if the site lists the same experiments - await page.goto("/deployment/general", { waitUntil: "networkidle" }); + // Verify if the site lists the same experiments + await page.goto("/deployment/general", { waitUntil: "networkidle" }); - const experimentsLocator = page.locator( - "div.options-table tr.option-experiments ul.option-array", - ); - await expect(experimentsLocator).toBeVisible(); + const experimentsLocator = page.locator( + "div.options-table tr.option-experiments ul.option-array", + ); + await expect(experimentsLocator).toBeVisible(); - // Firstly, check if all enabled experiments are listed - expect( - experimentsLocator.locator( - `li.option-array-item-${e2eFakeExperiment1}.option-enabled`, - ), - ).toBeVisible; - expect( - experimentsLocator.locator( - `li.option-array-item-${e2eFakeExperiment2}.option-enabled`, - ), - ).toBeVisible; + // Firstly, check if all enabled experiments are listed + expect( + experimentsLocator.locator( + `li.option-array-item-${e2eFakeExperiment1}.option-enabled`, + ), + ).toBeVisible; + expect( + experimentsLocator.locator( + `li.option-array-item-${e2eFakeExperiment2}.option-enabled`, + ), + ).toBeVisible; - // Secondly, check if available experiments are listed - for (const experiment of availableExperiments.safe) { - const experimentLocator = experimentsLocator.locator( - `li.option-array-item-${experiment}`, - ); - await expect(experimentLocator).toBeVisible(); - } + // Secondly, check if available experiments are listed + for (const experiment of availableExperiments.safe) { + const experimentLocator = experimentsLocator.locator( + `li.option-array-item-${experiment}`, + ); + await expect(experimentLocator).toBeVisible(); + } }); diff --git a/site/e2e/tests/deployment/licenses.spec.ts b/site/e2e/tests/deployment/licenses.spec.ts index 89546bbec8..ae95c6b277 100644 --- a/site/e2e/tests/deployment/licenses.spec.ts +++ b/site/e2e/tests/deployment/licenses.spec.ts @@ -2,29 +2,29 @@ import { expect, test } from "@playwright/test"; import { requiresEnterpriseLicense } from "../../helpers"; test("license was added successfully", async ({ page }) => { - requiresEnterpriseLicense(); + requiresEnterpriseLicense(); - await page.goto("/deployment/licenses", { waitUntil: "domcontentloaded" }); - const firstLicense = page.locator(".licenses > .license-card", { - hasText: "#1", - }); - await expect(firstLicense).toBeVisible(); + await page.goto("/deployment/licenses", { waitUntil: "domcontentloaded" }); + const firstLicense = page.locator(".licenses > .license-card", { + hasText: "#1", + }); + await expect(firstLicense).toBeVisible(); - // Trial vs. Enterprise? - const accountType = firstLicense.locator(".account-type"); - await expect(accountType).toHaveText("Enterprise"); + // Trial vs. Enterprise? + const accountType = firstLicense.locator(".account-type"); + await expect(accountType).toHaveText("Enterprise"); - // User limit 1/1 - const userLimit = firstLicense.locator(".user-limit"); - await expect(userLimit).toHaveText("1 / 1"); + // User limit 1/1 + const userLimit = firstLicense.locator(".user-limit"); + await expect(userLimit).toHaveText("1 / 1"); - // License should not be expired yet - const licenseExpires = firstLicense.locator(".license-expires"); - const licenseExpiresDate = new Date(await licenseExpires.innerText()); - const now = new Date(); - expect(licenseExpiresDate.getTime()).toBeGreaterThan(now.getTime()); + // License should not be expired yet + const licenseExpires = firstLicense.locator(".license-expires"); + const licenseExpiresDate = new Date(await licenseExpires.innerText()); + const now = new Date(); + expect(licenseExpiresDate.getTime()).toBeGreaterThan(now.getTime()); - // "Remove" button should be visible - const removeButton = firstLicense.locator(".remove-button"); - await expect(removeButton).toBeVisible(); + // "Remove" button should be visible + const removeButton = firstLicense.locator(".remove-button"); + await expect(removeButton).toBeVisible(); }); diff --git a/site/e2e/tests/deployment/network.spec.ts b/site/e2e/tests/deployment/network.spec.ts index d125a100d3..c2c6f0f1c9 100644 --- a/site/e2e/tests/deployment/network.spec.ts +++ b/site/e2e/tests/deployment/network.spec.ts @@ -1,40 +1,40 @@ import { test } from "@playwright/test"; import { API } from "api/api"; import { - setupApiCalls, - verifyConfigFlagArray, - verifyConfigFlagBoolean, - verifyConfigFlagDuration, - verifyConfigFlagNumber, - verifyConfigFlagString, + setupApiCalls, + verifyConfigFlagArray, + verifyConfigFlagBoolean, + verifyConfigFlagDuration, + verifyConfigFlagNumber, + verifyConfigFlagString, } from "../../api"; test("enabled network settings", async ({ page }) => { - await setupApiCalls(page); - const config = await API.getDeploymentConfig(); + await setupApiCalls(page); + const config = await API.getDeploymentConfig(); - await page.goto("/deployment/network", { waitUntil: "domcontentloaded" }); + await page.goto("/deployment/network", { waitUntil: "domcontentloaded" }); - await verifyConfigFlagString(page, config, "access-url"); - await verifyConfigFlagBoolean(page, config, "block-direct-connections"); - await verifyConfigFlagBoolean(page, config, "browser-only"); - await verifyConfigFlagBoolean(page, config, "derp-force-websockets"); - await verifyConfigFlagBoolean(page, config, "derp-server-enable"); - await verifyConfigFlagString(page, config, "derp-server-region-code"); - await verifyConfigFlagString(page, config, "derp-server-region-code"); - await verifyConfigFlagNumber(page, config, "derp-server-region-id"); - await verifyConfigFlagString(page, config, "derp-server-region-name"); - await verifyConfigFlagArray(page, config, "derp-server-stun-addresses"); - await verifyConfigFlagBoolean(page, config, "disable-password-auth"); - await verifyConfigFlagBoolean(page, config, "disable-session-expiry-refresh"); - await verifyConfigFlagDuration(page, config, "max-token-lifetime"); - await verifyConfigFlagDuration(page, config, "proxy-health-interval"); - await verifyConfigFlagBoolean(page, config, "redirect-to-access-url"); - await verifyConfigFlagBoolean(page, config, "secure-auth-cookie"); - await verifyConfigFlagDuration(page, config, "session-duration"); - await verifyConfigFlagString(page, config, "tls-address"); - await verifyConfigFlagBoolean(page, config, "tls-allow-insecure-ciphers"); - await verifyConfigFlagString(page, config, "tls-client-auth"); - await verifyConfigFlagBoolean(page, config, "tls-enable"); - await verifyConfigFlagString(page, config, "tls-min-version"); + await verifyConfigFlagString(page, config, "access-url"); + await verifyConfigFlagBoolean(page, config, "block-direct-connections"); + await verifyConfigFlagBoolean(page, config, "browser-only"); + await verifyConfigFlagBoolean(page, config, "derp-force-websockets"); + await verifyConfigFlagBoolean(page, config, "derp-server-enable"); + await verifyConfigFlagString(page, config, "derp-server-region-code"); + await verifyConfigFlagString(page, config, "derp-server-region-code"); + await verifyConfigFlagNumber(page, config, "derp-server-region-id"); + await verifyConfigFlagString(page, config, "derp-server-region-name"); + await verifyConfigFlagArray(page, config, "derp-server-stun-addresses"); + await verifyConfigFlagBoolean(page, config, "disable-password-auth"); + await verifyConfigFlagBoolean(page, config, "disable-session-expiry-refresh"); + await verifyConfigFlagDuration(page, config, "max-token-lifetime"); + await verifyConfigFlagDuration(page, config, "proxy-health-interval"); + await verifyConfigFlagBoolean(page, config, "redirect-to-access-url"); + await verifyConfigFlagBoolean(page, config, "secure-auth-cookie"); + await verifyConfigFlagDuration(page, config, "session-duration"); + await verifyConfigFlagString(page, config, "tls-address"); + await verifyConfigFlagBoolean(page, config, "tls-allow-insecure-ciphers"); + await verifyConfigFlagString(page, config, "tls-client-auth"); + await verifyConfigFlagBoolean(page, config, "tls-enable"); + await verifyConfigFlagString(page, config, "tls-min-version"); }); diff --git a/site/e2e/tests/deployment/observability.spec.ts b/site/e2e/tests/deployment/observability.spec.ts index 7030ea3508..f252fd3784 100644 --- a/site/e2e/tests/deployment/observability.spec.ts +++ b/site/e2e/tests/deployment/observability.spec.ts @@ -1,39 +1,39 @@ import { test } from "@playwright/test"; import { API } from "api/api"; import { - setupApiCalls, - verifyConfigFlagArray, - verifyConfigFlagBoolean, - verifyConfigFlagDuration, - verifyConfigFlagEmpty, - verifyConfigFlagString, + setupApiCalls, + verifyConfigFlagArray, + verifyConfigFlagBoolean, + verifyConfigFlagDuration, + verifyConfigFlagEmpty, + verifyConfigFlagString, } from "../../api"; test("enabled observability settings", async ({ page }) => { - await setupApiCalls(page); - const config = await API.getDeploymentConfig(); + await setupApiCalls(page); + const config = await API.getDeploymentConfig(); - await page.goto("/deployment/observability", { - waitUntil: "domcontentloaded", - }); + await page.goto("/deployment/observability", { + waitUntil: "domcontentloaded", + }); - await verifyConfigFlagBoolean(page, config, "trace-logs"); - await verifyConfigFlagBoolean(page, config, "enable-terraform-debug-mode"); - await verifyConfigFlagBoolean(page, config, "enable-terraform-debug-mode"); - await verifyConfigFlagDuration(page, config, "health-check-refresh"); - await verifyConfigFlagEmpty(page, "health-check-threshold-database"); - await verifyConfigFlagString(page, config, "log-human"); - await verifyConfigFlagString(page, config, "prometheus-address"); - await verifyConfigFlagArray( - page, - config, - "prometheus-aggregate-agent-stats-by", - ); - await verifyConfigFlagBoolean(page, config, "prometheus-collect-agent-stats"); - await verifyConfigFlagBoolean(page, config, "prometheus-collect-db-metrics"); - await verifyConfigFlagBoolean(page, config, "prometheus-enable"); - await verifyConfigFlagBoolean(page, config, "trace-datadog"); - await verifyConfigFlagBoolean(page, config, "trace"); - await verifyConfigFlagBoolean(page, config, "verbose"); - await verifyConfigFlagBoolean(page, config, "pprof-enable"); + await verifyConfigFlagBoolean(page, config, "trace-logs"); + await verifyConfigFlagBoolean(page, config, "enable-terraform-debug-mode"); + await verifyConfigFlagBoolean(page, config, "enable-terraform-debug-mode"); + await verifyConfigFlagDuration(page, config, "health-check-refresh"); + await verifyConfigFlagEmpty(page, "health-check-threshold-database"); + await verifyConfigFlagString(page, config, "log-human"); + await verifyConfigFlagString(page, config, "prometheus-address"); + await verifyConfigFlagArray( + page, + config, + "prometheus-aggregate-agent-stats-by", + ); + await verifyConfigFlagBoolean(page, config, "prometheus-collect-agent-stats"); + await verifyConfigFlagBoolean(page, config, "prometheus-collect-db-metrics"); + await verifyConfigFlagBoolean(page, config, "prometheus-enable"); + await verifyConfigFlagBoolean(page, config, "trace-datadog"); + await verifyConfigFlagBoolean(page, config, "trace"); + await verifyConfigFlagBoolean(page, config, "verbose"); + await verifyConfigFlagBoolean(page, config, "pprof-enable"); }); diff --git a/site/e2e/tests/deployment/security.spec.ts b/site/e2e/tests/deployment/security.spec.ts index c91e9d7ef6..b9c202a648 100644 --- a/site/e2e/tests/deployment/security.spec.ts +++ b/site/e2e/tests/deployment/security.spec.ts @@ -2,45 +2,45 @@ import type { Page } from "@playwright/test"; import { expect, test } from "@playwright/test"; import { API, type DeploymentConfig } from "api/api"; import { - findConfigOption, - setupApiCalls, - verifyConfigFlagBoolean, - verifyConfigFlagNumber, - verifyConfigFlagString, + findConfigOption, + setupApiCalls, + verifyConfigFlagBoolean, + verifyConfigFlagNumber, + verifyConfigFlagString, } from "../../api"; test("enabled security settings", async ({ page }) => { - await setupApiCalls(page); - const config = await API.getDeploymentConfig(); + await setupApiCalls(page); + const config = await API.getDeploymentConfig(); - await page.goto("/deployment/security", { waitUntil: "domcontentloaded" }); + await page.goto("/deployment/security", { waitUntil: "domcontentloaded" }); - await verifyConfigFlagString(page, config, "ssh-keygen-algorithm"); - await verifyConfigFlagBoolean(page, config, "secure-auth-cookie"); - await verifyConfigFlagBoolean(page, config, "disable-owner-workspace-access"); + await verifyConfigFlagString(page, config, "ssh-keygen-algorithm"); + await verifyConfigFlagBoolean(page, config, "secure-auth-cookie"); + await verifyConfigFlagBoolean(page, config, "disable-owner-workspace-access"); - await verifyConfigFlagBoolean(page, config, "tls-redirect-http-to-https"); - await verifyStrictTransportSecurity(page, config); - await verifyConfigFlagString(page, config, "tls-address"); - await verifyConfigFlagBoolean(page, config, "tls-allow-insecure-ciphers"); - await verifyConfigFlagString(page, config, "tls-client-auth"); - await verifyConfigFlagBoolean(page, config, "tls-enable"); - await verifyConfigFlagString(page, config, "tls-min-version"); + await verifyConfigFlagBoolean(page, config, "tls-redirect-http-to-https"); + await verifyStrictTransportSecurity(page, config); + await verifyConfigFlagString(page, config, "tls-address"); + await verifyConfigFlagBoolean(page, config, "tls-allow-insecure-ciphers"); + await verifyConfigFlagString(page, config, "tls-client-auth"); + await verifyConfigFlagBoolean(page, config, "tls-enable"); + await verifyConfigFlagString(page, config, "tls-min-version"); }); async function verifyStrictTransportSecurity( - page: Page, - config: DeploymentConfig, + page: Page, + config: DeploymentConfig, ) { - const flag = "strict-transport-security"; - const opt = findConfigOption(config, flag); - if (opt.value !== 0) { - await verifyConfigFlagNumber(page, config, flag); - return; - } + const flag = "strict-transport-security"; + const opt = findConfigOption(config, flag); + if (opt.value !== 0) { + await verifyConfigFlagNumber(page, config, flag); + return; + } - const configOption = page.locator( - `div.options-table .option-${flag} .option-value-string`, - ); - await expect(configOption).toHaveText("Disabled"); + const configOption = page.locator( + `div.options-table .option-${flag} .option-value-string`, + ); + await expect(configOption).toHaveText("Disabled"); } diff --git a/site/e2e/tests/deployment/userAuth.spec.ts b/site/e2e/tests/deployment/userAuth.spec.ts index 8dd8a3af49..11d8fc5bcc 100644 --- a/site/e2e/tests/deployment/userAuth.spec.ts +++ b/site/e2e/tests/deployment/userAuth.spec.ts @@ -1,33 +1,33 @@ import { test } from "@playwright/test"; import { API } from "api/api"; import { - setupApiCalls, - verifyConfigFlagArray, - verifyConfigFlagBoolean, - verifyConfigFlagEntries, - verifyConfigFlagString, + setupApiCalls, + verifyConfigFlagArray, + verifyConfigFlagBoolean, + verifyConfigFlagEntries, + verifyConfigFlagString, } from "../../api"; test("login with OIDC", async ({ page }) => { - await setupApiCalls(page); - const config = await API.getDeploymentConfig(); + await setupApiCalls(page); + const config = await API.getDeploymentConfig(); - await page.goto("/deployment/userauth", { waitUntil: "domcontentloaded" }); + await page.goto("/deployment/userauth", { waitUntil: "domcontentloaded" }); - await verifyConfigFlagBoolean(page, config, "oidc-group-auto-create"); - await verifyConfigFlagBoolean(page, config, "oidc-allow-signups"); - await verifyConfigFlagEntries(page, config, "oidc-auth-url-params"); - await verifyConfigFlagString(page, config, "oidc-client-id"); - await verifyConfigFlagArray(page, config, "oidc-email-domain"); - await verifyConfigFlagString(page, config, "oidc-email-field"); - await verifyConfigFlagEntries(page, config, "oidc-group-mapping"); - await verifyConfigFlagBoolean(page, config, "oidc-ignore-email-verified"); - await verifyConfigFlagBoolean(page, config, "oidc-ignore-userinfo"); - await verifyConfigFlagString(page, config, "oidc-issuer-url"); - await verifyConfigFlagString(page, config, "oidc-group-regex-filter"); - await verifyConfigFlagArray(page, config, "oidc-scopes"); - await verifyConfigFlagEntries(page, config, "oidc-user-role-mapping"); - await verifyConfigFlagString(page, config, "oidc-username-field"); - await verifyConfigFlagString(page, config, "oidc-sign-in-text"); - await verifyConfigFlagString(page, config, "oidc-icon-url"); + await verifyConfigFlagBoolean(page, config, "oidc-group-auto-create"); + await verifyConfigFlagBoolean(page, config, "oidc-allow-signups"); + await verifyConfigFlagEntries(page, config, "oidc-auth-url-params"); + await verifyConfigFlagString(page, config, "oidc-client-id"); + await verifyConfigFlagArray(page, config, "oidc-email-domain"); + await verifyConfigFlagString(page, config, "oidc-email-field"); + await verifyConfigFlagEntries(page, config, "oidc-group-mapping"); + await verifyConfigFlagBoolean(page, config, "oidc-ignore-email-verified"); + await verifyConfigFlagBoolean(page, config, "oidc-ignore-userinfo"); + await verifyConfigFlagString(page, config, "oidc-issuer-url"); + await verifyConfigFlagString(page, config, "oidc-group-regex-filter"); + await verifyConfigFlagArray(page, config, "oidc-scopes"); + await verifyConfigFlagEntries(page, config, "oidc-user-role-mapping"); + await verifyConfigFlagString(page, config, "oidc-username-field"); + await verifyConfigFlagString(page, config, "oidc-sign-in-text"); + await verifyConfigFlagString(page, config, "oidc-icon-url"); }); diff --git a/site/e2e/tests/deployment/workspaceProxies.spec.ts b/site/e2e/tests/deployment/workspaceProxies.spec.ts index 64e3177aa0..6aad06a46b 100644 --- a/site/e2e/tests/deployment/workspaceProxies.spec.ts +++ b/site/e2e/tests/deployment/workspaceProxies.spec.ts @@ -6,100 +6,100 @@ import { randomName, requiresEnterpriseLicense } from "../../helpers"; import { startWorkspaceProxy, stopWorkspaceProxy } from "../../proxy"; test("default proxy is online", async ({ page }) => { - requiresEnterpriseLicense(); - await setupApiCalls(page); + requiresEnterpriseLicense(); + await setupApiCalls(page); - await page.goto("/deployment/workspace-proxies", { - waitUntil: "domcontentloaded", - }); + await page.goto("/deployment/workspace-proxies", { + waitUntil: "domcontentloaded", + }); - // Verify if the default proxy is healthy - const workspaceProxyPrimary = page.locator( - `table.MuiTable-root tr[data-testid="primary"]`, - ); + // Verify if the default proxy is healthy + const workspaceProxyPrimary = page.locator( + `table.MuiTable-root tr[data-testid="primary"]`, + ); - const workspaceProxyName = workspaceProxyPrimary.locator("td.name span"); - const workspaceProxyURL = workspaceProxyPrimary.locator("td.url"); - const workspaceProxyStatus = workspaceProxyPrimary.locator("td.status span"); + const workspaceProxyName = workspaceProxyPrimary.locator("td.name span"); + const workspaceProxyURL = workspaceProxyPrimary.locator("td.url"); + const workspaceProxyStatus = workspaceProxyPrimary.locator("td.status span"); - await expect(workspaceProxyName).toHaveText("Default"); - await expect(workspaceProxyURL).toHaveText(`http://localhost:${coderPort}`); - await expect(workspaceProxyStatus).toHaveText("Healthy"); + await expect(workspaceProxyName).toHaveText("Default"); + await expect(workspaceProxyURL).toHaveText(`http://localhost:${coderPort}`); + await expect(workspaceProxyStatus).toHaveText("Healthy"); }); test("custom proxy is online", async ({ page }) => { - requiresEnterpriseLicense(); - await setupApiCalls(page); + requiresEnterpriseLicense(); + await setupApiCalls(page); - const proxyName = randomName(); + const proxyName = randomName(); - // Register workspace proxy - const proxyResponse = await API.createWorkspaceProxy({ - name: proxyName, - display_name: "", - icon: "/emojis/1f1e7-1f1f7.png", - }); - expect(proxyResponse.proxy_token).toBeDefined(); + // Register workspace proxy + const proxyResponse = await API.createWorkspaceProxy({ + name: proxyName, + display_name: "", + icon: "/emojis/1f1e7-1f1f7.png", + }); + expect(proxyResponse.proxy_token).toBeDefined(); - // Start "wsproxy server" - const proxyServer = await startWorkspaceProxy(proxyResponse.proxy_token); - await waitUntilWorkspaceProxyIsHealthy(page, proxyName); + // Start "wsproxy server" + const proxyServer = await startWorkspaceProxy(proxyResponse.proxy_token); + await waitUntilWorkspaceProxyIsHealthy(page, proxyName); - // Verify if custom proxy is healthy - await page.goto("/deployment/workspace-proxies", { - waitUntil: "domcontentloaded", - }); + // Verify if custom proxy is healthy + await page.goto("/deployment/workspace-proxies", { + waitUntil: "domcontentloaded", + }); - const workspaceProxy = page.locator("table.MuiTable-root tr", { - hasText: proxyName, - }); + const workspaceProxy = page.locator("table.MuiTable-root tr", { + hasText: proxyName, + }); - const workspaceProxyName = workspaceProxy.locator("td.name span"); - const workspaceProxyURL = workspaceProxy.locator("td.url"); - const workspaceProxyStatus = workspaceProxy.locator("td.status span"); + const workspaceProxyName = workspaceProxy.locator("td.name span"); + const workspaceProxyURL = workspaceProxy.locator("td.url"); + const workspaceProxyStatus = workspaceProxy.locator("td.status span"); - await expect(workspaceProxyName).toHaveText(proxyName); - await expect(workspaceProxyURL).toHaveText( - `http://127.0.0.1:${workspaceProxyPort}`, - ); - await expect(workspaceProxyStatus).toHaveText("Healthy"); + await expect(workspaceProxyName).toHaveText(proxyName); + await expect(workspaceProxyURL).toHaveText( + `http://127.0.0.1:${workspaceProxyPort}`, + ); + await expect(workspaceProxyStatus).toHaveText("Healthy"); - // Tear down the proxy - await stopWorkspaceProxy(proxyServer); + // Tear down the proxy + await stopWorkspaceProxy(proxyServer); }); const waitUntilWorkspaceProxyIsHealthy = async ( - page: Page, - proxyName: string, + page: Page, + proxyName: string, ) => { - await page.goto("/deployment/workspace-proxies", { - waitUntil: "domcontentloaded", - }); + await page.goto("/deployment/workspace-proxies", { + waitUntil: "domcontentloaded", + }); - const maxRetries = 30; - const retryIntervalMs = 1000; - let retries = 0; - while (retries < maxRetries) { - await page.reload(); + const maxRetries = 30; + const retryIntervalMs = 1000; + let retries = 0; + while (retries < maxRetries) { + await page.reload(); - const workspaceProxy = page.locator("table.MuiTable-root tr", { - hasText: proxyName, - }); - const workspaceProxyStatus = workspaceProxy.locator("td.status span"); + const workspaceProxy = page.locator("table.MuiTable-root tr", { + hasText: proxyName, + }); + const workspaceProxyStatus = workspaceProxy.locator("td.status span"); - try { - await expect(workspaceProxyStatus).toHaveText("Healthy", { - timeout: 1_000, - }); - return; // healthy! - } catch { - retries++; - await new Promise((resolve) => setTimeout(resolve, retryIntervalMs)); - } - } - throw new Error( - `Workspace proxy "${proxyName}" is unhealthy after ${ - maxRetries * retryIntervalMs - }ms`, - ); + try { + await expect(workspaceProxyStatus).toHaveText("Healthy", { + timeout: 1_000, + }); + return; // healthy! + } catch { + retries++; + await new Promise((resolve) => setTimeout(resolve, retryIntervalMs)); + } + } + throw new Error( + `Workspace proxy "${proxyName}" is unhealthy after ${ + maxRetries * retryIntervalMs + }ms`, + ); }; diff --git a/site/e2e/tests/externalAuth.spec.ts b/site/e2e/tests/externalAuth.spec.ts index 3148be465f..bb882dfcdd 100644 --- a/site/e2e/tests/externalAuth.spec.ts +++ b/site/e2e/tests/externalAuth.spec.ts @@ -3,32 +3,32 @@ import { test } from "@playwright/test"; import type { ExternalAuthDevice } from "api/typesGenerated"; import { gitAuth } from "../constants"; import { - Awaiter, - createServer, - createTemplate, - createWorkspace, - echoResponsesWithExternalAuth, + Awaiter, + createServer, + createTemplate, + createWorkspace, + echoResponsesWithExternalAuth, } from "../helpers"; import { beforeCoderTest, resetExternalAuthKey } from "../hooks"; test.beforeAll(async ({ baseURL }) => { - const srv = await createServer(gitAuth.webPort); + const srv = await createServer(gitAuth.webPort); - // The GitHub validate endpoint returns the currently authenticated user! - srv.use(gitAuth.validatePath, (req, res) => { - res.write(JSON.stringify(ghUser)); - res.end(); - }); - srv.use(gitAuth.tokenPath, (req, res) => { - const r = (Math.random() + 1).toString(36).substring(7); - res.write(JSON.stringify({ access_token: r })); - res.end(); - }); - srv.use(gitAuth.authPath, (req, res) => { - res.redirect( - `${baseURL}/external-auth/${gitAuth.webProvider}/callback?code=1234&state=${req.query.state}`, - ); - }); + // The GitHub validate endpoint returns the currently authenticated user! + srv.use(gitAuth.validatePath, (req, res) => { + res.write(JSON.stringify(ghUser)); + res.end(); + }); + srv.use(gitAuth.tokenPath, (req, res) => { + const r = (Math.random() + 1).toString(36).substring(7); + res.write(JSON.stringify({ access_token: r })); + res.end(); + }); + srv.use(gitAuth.authPath, (req, res) => { + res.redirect( + `${baseURL}/external-auth/${gitAuth.webProvider}/callback?code=1234&state=${req.query.state}`, + ); + }); }); test.beforeEach(async ({ context }) => resetExternalAuthKey(context)); @@ -37,130 +37,130 @@ test.beforeEach(({ page }) => beforeCoderTest(page)); // Ensures that a Git auth provider with the device flow functions and completes! test("external auth device", async ({ page }) => { - const device: ExternalAuthDevice = { - device_code: "1234", - user_code: "1234-5678", - expires_in: 900, - interval: 1, - verification_uri: "", - }; + const device: ExternalAuthDevice = { + device_code: "1234", + user_code: "1234-5678", + expires_in: 900, + interval: 1, + verification_uri: "", + }; - // Start a server to mock the GitHub API. - const srv = await createServer(gitAuth.devicePort); - srv.use(gitAuth.validatePath, (req, res) => { - res.write(JSON.stringify(ghUser)); - res.end(); - }); - srv.use(gitAuth.codePath, (req, res) => { - res.write(JSON.stringify(device)); - res.end(); - }); - srv.use(gitAuth.installationsPath, (req, res) => { - res.write(JSON.stringify(ghInstall)); - res.end(); - }); + // Start a server to mock the GitHub API. + const srv = await createServer(gitAuth.devicePort); + srv.use(gitAuth.validatePath, (req, res) => { + res.write(JSON.stringify(ghUser)); + res.end(); + }); + srv.use(gitAuth.codePath, (req, res) => { + res.write(JSON.stringify(device)); + res.end(); + }); + srv.use(gitAuth.installationsPath, (req, res) => { + res.write(JSON.stringify(ghInstall)); + res.end(); + }); - const token = { - access_token: "", - error: "authorization_pending", - error_description: "", - }; - // First we send a result from the API that the token hasn't been - // authorized yet to ensure the UI reacts properly. - const sentPending = new Awaiter(); - srv.use(gitAuth.tokenPath, (req, res) => { - res.write(JSON.stringify(token)); - res.end(); - sentPending.done(); - }); + const token = { + access_token: "", + error: "authorization_pending", + error_description: "", + }; + // First we send a result from the API that the token hasn't been + // authorized yet to ensure the UI reacts properly. + const sentPending = new Awaiter(); + srv.use(gitAuth.tokenPath, (req, res) => { + res.write(JSON.stringify(token)); + res.end(); + sentPending.done(); + }); - await page.goto(`/external-auth/${gitAuth.deviceProvider}`, { - waitUntil: "domcontentloaded", - }); - await page.getByText(device.user_code).isVisible(); - await sentPending.wait(); - // Update the token to be valid and ensure the UI updates! - token.error = ""; - token.access_token = "hello-world"; - await page.waitForSelector("text=1 organization authorized"); + await page.goto(`/external-auth/${gitAuth.deviceProvider}`, { + waitUntil: "domcontentloaded", + }); + await page.getByText(device.user_code).isVisible(); + await sentPending.wait(); + // Update the token to be valid and ensure the UI updates! + token.error = ""; + token.access_token = "hello-world"; + await page.waitForSelector("text=1 organization authorized"); }); test("external auth web", async ({ page }) => { - await page.goto(`/external-auth/${gitAuth.webProvider}`, { - waitUntil: "domcontentloaded", - }); - // This endpoint doesn't have the installations URL set intentionally! - await page.waitForSelector("text=You've authenticated with GitHub!"); + await page.goto(`/external-auth/${gitAuth.webProvider}`, { + waitUntil: "domcontentloaded", + }); + // This endpoint doesn't have the installations URL set intentionally! + await page.waitForSelector("text=You've authenticated with GitHub!"); }); test("successful external auth from workspace", async ({ page }) => { - const templateName = await createTemplate( - page, - echoResponsesWithExternalAuth([ - { id: gitAuth.webProvider, optional: false }, - ]), - ); + const templateName = await createTemplate( + page, + echoResponsesWithExternalAuth([ + { id: gitAuth.webProvider, optional: false }, + ]), + ); - await createWorkspace(page, templateName, [], [], gitAuth.webProvider); + await createWorkspace(page, templateName, [], [], gitAuth.webProvider); }); const ghUser: Endpoints["GET /user"]["response"]["data"] = { - login: "kylecarbs", - id: 7122116, - node_id: "MDQ6VXNlcjcxMjIxMTY=", - avatar_url: "https://avatars.githubusercontent.com/u/7122116?v=4", - gravatar_id: "", - url: "https://api.github.com/users/kylecarbs", - html_url: "https://github.com/kylecarbs", - followers_url: "https://api.github.com/users/kylecarbs/followers", - following_url: - "https://api.github.com/users/kylecarbs/following{/other_user}", - gists_url: "https://api.github.com/users/kylecarbs/gists{/gist_id}", - starred_url: "https://api.github.com/users/kylecarbs/starred{/owner}{/repo}", - subscriptions_url: "https://api.github.com/users/kylecarbs/subscriptions", - organizations_url: "https://api.github.com/users/kylecarbs/orgs", - repos_url: "https://api.github.com/users/kylecarbs/repos", - events_url: "https://api.github.com/users/kylecarbs/events{/privacy}", - received_events_url: "https://api.github.com/users/kylecarbs/received_events", - type: "User", - site_admin: false, - name: "Kyle Carberry", - company: "@coder", - blog: "https://carberry.com", - location: "Austin, TX", - email: "kyle@carberry.com", - hireable: null, - bio: "hey there", - twitter_username: "kylecarbs", - public_repos: 52, - public_gists: 9, - followers: 208, - following: 31, - created_at: "2014-04-01T02:24:41Z", - updated_at: "2023-06-26T13:03:09Z", + login: "kylecarbs", + id: 7122116, + node_id: "MDQ6VXNlcjcxMjIxMTY=", + avatar_url: "https://avatars.githubusercontent.com/u/7122116?v=4", + gravatar_id: "", + url: "https://api.github.com/users/kylecarbs", + html_url: "https://github.com/kylecarbs", + followers_url: "https://api.github.com/users/kylecarbs/followers", + following_url: + "https://api.github.com/users/kylecarbs/following{/other_user}", + gists_url: "https://api.github.com/users/kylecarbs/gists{/gist_id}", + starred_url: "https://api.github.com/users/kylecarbs/starred{/owner}{/repo}", + subscriptions_url: "https://api.github.com/users/kylecarbs/subscriptions", + organizations_url: "https://api.github.com/users/kylecarbs/orgs", + repos_url: "https://api.github.com/users/kylecarbs/repos", + events_url: "https://api.github.com/users/kylecarbs/events{/privacy}", + received_events_url: "https://api.github.com/users/kylecarbs/received_events", + type: "User", + site_admin: false, + name: "Kyle Carberry", + company: "@coder", + blog: "https://carberry.com", + location: "Austin, TX", + email: "kyle@carberry.com", + hireable: null, + bio: "hey there", + twitter_username: "kylecarbs", + public_repos: 52, + public_gists: 9, + followers: 208, + following: 31, + created_at: "2014-04-01T02:24:41Z", + updated_at: "2023-06-26T13:03:09Z", }; const ghInstall: Endpoints["GET /user/installations"]["response"]["data"] = { - installations: [ - { - id: 1, - access_tokens_url: "", - account: ghUser, - app_id: 1, - app_slug: "coder", - created_at: "2014-04-01T02:24:41Z", - events: [], - html_url: "", - permissions: {}, - repositories_url: "", - repository_selection: "all", - single_file_name: "", - suspended_at: null, - suspended_by: null, - target_id: 1, - target_type: "", - updated_at: "2023-06-26T13:03:09Z", - }, - ], - total_count: 1, + installations: [ + { + id: 1, + access_tokens_url: "", + account: ghUser, + app_id: 1, + app_slug: "coder", + created_at: "2014-04-01T02:24:41Z", + events: [], + html_url: "", + permissions: {}, + repositories_url: "", + repository_selection: "all", + single_file_name: "", + suspended_at: null, + suspended_by: null, + target_id: 1, + target_type: "", + updated_at: "2023-06-26T13:03:09Z", + }, + ], + total_count: 1, }; diff --git a/site/e2e/tests/groups/addMembers.spec.ts b/site/e2e/tests/groups/addMembers.spec.ts index a0e0d05fb4..1bdf5a3da0 100644 --- a/site/e2e/tests/groups/addMembers.spec.ts +++ b/site/e2e/tests/groups/addMembers.spec.ts @@ -1,9 +1,9 @@ import { expect, test } from "@playwright/test"; import { - createGroup, - createUser, - getCurrentOrgId, - setupApiCalls, + createGroup, + createUser, + getCurrentOrgId, + setupApiCalls, } from "../../api"; import { requiresEnterpriseLicense } from "../../helpers"; import { beforeCoderTest } from "../../hooks"; @@ -11,24 +11,24 @@ import { beforeCoderTest } from "../../hooks"; test.beforeEach(async ({ page }) => await beforeCoderTest(page)); test("add members", async ({ page, baseURL }) => { - requiresEnterpriseLicense(); - await setupApiCalls(page); - const orgId = await getCurrentOrgId(); - const group = await createGroup(orgId); - const numberOfMembers = 3; - const users = await Promise.all( - Array.from({ length: numberOfMembers }, () => createUser(orgId)), - ); + requiresEnterpriseLicense(); + await setupApiCalls(page); + const orgId = await getCurrentOrgId(); + const group = await createGroup(orgId); + const numberOfMembers = 3; + const users = await Promise.all( + Array.from({ length: numberOfMembers }, () => createUser(orgId)), + ); - await page.goto(`${baseURL}/groups/${group.name}`, { - waitUntil: "domcontentloaded", - }); - await expect(page).toHaveTitle(`${group.display_name} - Coder`); + await page.goto(`${baseURL}/groups/${group.name}`, { + waitUntil: "domcontentloaded", + }); + await expect(page).toHaveTitle(`${group.display_name} - Coder`); - for (const user of users) { - await page.getByPlaceholder("User email or username").fill(user.username); - await page.getByRole("option", { name: user.email }).click(); - await page.getByRole("button", { name: "Add user" }).click(); - await expect(page.getByRole("row", { name: user.username })).toBeVisible(); - } + for (const user of users) { + await page.getByPlaceholder("User email or username").fill(user.username); + await page.getByRole("option", { name: user.email }).click(); + await page.getByRole("button", { name: "Add user" }).click(); + await expect(page.getByRole("row", { name: user.username })).toBeVisible(); + } }); diff --git a/site/e2e/tests/groups/addUsersToDefaultGroup.spec.ts b/site/e2e/tests/groups/addUsersToDefaultGroup.spec.ts index 867d1e9782..786341bfd4 100644 --- a/site/e2e/tests/groups/addUsersToDefaultGroup.spec.ts +++ b/site/e2e/tests/groups/addUsersToDefaultGroup.spec.ts @@ -8,25 +8,25 @@ test.beforeEach(async ({ page }) => await beforeCoderTest(page)); const DEFAULT_GROUP_NAME = "Everyone"; test(`Every user should be automatically added to the default '${DEFAULT_GROUP_NAME}' group upon creation`, async ({ - page, - baseURL, + page, + baseURL, }) => { - requiresEnterpriseLicense(); - await setupApiCalls(page); - const orgId = await getCurrentOrgId(); - const numberOfMembers = 3; - const users = await Promise.all( - Array.from({ length: numberOfMembers }, () => createUser(orgId)), - ); + requiresEnterpriseLicense(); + await setupApiCalls(page); + const orgId = await getCurrentOrgId(); + const numberOfMembers = 3; + const users = await Promise.all( + Array.from({ length: numberOfMembers }, () => createUser(orgId)), + ); - await page.goto(`${baseURL}/groups`, { waitUntil: "domcontentloaded" }); - await expect(page).toHaveTitle("Groups - Coder"); + await page.goto(`${baseURL}/groups`, { waitUntil: "domcontentloaded" }); + await expect(page).toHaveTitle("Groups - Coder"); - const groupRow = page.getByRole("row", { name: DEFAULT_GROUP_NAME }); - await groupRow.click(); - await expect(page).toHaveTitle(`${DEFAULT_GROUP_NAME} - Coder`); + const groupRow = page.getByRole("row", { name: DEFAULT_GROUP_NAME }); + await groupRow.click(); + await expect(page).toHaveTitle(`${DEFAULT_GROUP_NAME} - Coder`); - for (const user of users) { - await expect(page.getByRole("row", { name: user.username })).toBeVisible(); - } + for (const user of users) { + await expect(page.getByRole("row", { name: user.username })).toBeVisible(); + } }); diff --git a/site/e2e/tests/groups/createGroup.spec.ts b/site/e2e/tests/groups/createGroup.spec.ts index a72da1bc26..d614415ee9 100644 --- a/site/e2e/tests/groups/createGroup.spec.ts +++ b/site/e2e/tests/groups/createGroup.spec.ts @@ -5,26 +5,26 @@ import { beforeCoderTest } from "../../hooks"; test.beforeEach(async ({ page }) => await beforeCoderTest(page)); test("create group", async ({ page, baseURL }) => { - requiresEnterpriseLicense(); - await page.goto(`${baseURL}/groups`, { waitUntil: "domcontentloaded" }); - await expect(page).toHaveTitle("Groups - Coder"); + requiresEnterpriseLicense(); + await page.goto(`${baseURL}/groups`, { waitUntil: "domcontentloaded" }); + await expect(page).toHaveTitle("Groups - Coder"); - await page.getByText("Create group").click(); - await expect(page).toHaveTitle("Create Group - Coder"); + await page.getByText("Create group").click(); + await expect(page).toHaveTitle("Create Group - Coder"); - const name = randomName(); - const groupValues = { - name: name, - displayName: `Display Name for ${name}`, - avatarURL: "/emojis/1f60d.png", - }; + const name = randomName(); + const groupValues = { + name: name, + displayName: `Display Name for ${name}`, + avatarURL: "/emojis/1f60d.png", + }; - await page.getByLabel("Name", { exact: true }).fill(groupValues.name); - await page.getByLabel("Display Name").fill(groupValues.displayName); - await page.getByLabel("Avatar URL").fill(groupValues.avatarURL); - await page.getByRole("button", { name: "Submit" }).click(); + await page.getByLabel("Name", { exact: true }).fill(groupValues.name); + await page.getByLabel("Display Name").fill(groupValues.displayName); + await page.getByLabel("Avatar URL").fill(groupValues.avatarURL); + await page.getByRole("button", { name: "Submit" }).click(); - await expect(page).toHaveTitle(`${groupValues.displayName} - Coder`); - await expect(page.getByText(groupValues.displayName)).toBeVisible(); - await expect(page.getByText("No members yet")).toBeVisible(); + await expect(page).toHaveTitle(`${groupValues.displayName} - Coder`); + await expect(page.getByText(groupValues.displayName)).toBeVisible(); + await expect(page.getByText("No members yet")).toBeVisible(); }); diff --git a/site/e2e/tests/groups/navigateToGroupPage.spec.ts b/site/e2e/tests/groups/navigateToGroupPage.spec.ts index 04f015083d..3cda616cff 100644 --- a/site/e2e/tests/groups/navigateToGroupPage.spec.ts +++ b/site/e2e/tests/groups/navigateToGroupPage.spec.ts @@ -6,18 +6,18 @@ import { beforeCoderTest } from "../../hooks"; test.beforeEach(async ({ page }) => await beforeCoderTest(page)); test("navigate to group page", async ({ page, baseURL }) => { - requiresEnterpriseLicense(); - await setupApiCalls(page); - const orgId = await getCurrentOrgId(); - const group = await createGroup(orgId); + requiresEnterpriseLicense(); + await setupApiCalls(page); + const orgId = await getCurrentOrgId(); + const group = await createGroup(orgId); - await page.goto(`${baseURL}/users`, { waitUntil: "domcontentloaded" }); - await expect(page).toHaveTitle("Users - Coder"); + await page.goto(`${baseURL}/users`, { waitUntil: "domcontentloaded" }); + await expect(page).toHaveTitle("Users - Coder"); - await page.getByRole("link", { name: "Groups" }).click(); - await expect(page).toHaveTitle("Groups - Coder"); + await page.getByRole("link", { name: "Groups" }).click(); + await expect(page).toHaveTitle("Groups - Coder"); - const groupRow = page.getByRole("row", { name: group.display_name }); - await groupRow.click(); - await expect(page).toHaveTitle(`${group.display_name} - Coder`); + const groupRow = page.getByRole("row", { name: group.display_name }); + await groupRow.click(); + await expect(page).toHaveTitle(`${group.display_name} - Coder`); }); diff --git a/site/e2e/tests/groups/removeGroup.spec.ts b/site/e2e/tests/groups/removeGroup.spec.ts index c9b5256bf9..e058ccf495 100644 --- a/site/e2e/tests/groups/removeGroup.spec.ts +++ b/site/e2e/tests/groups/removeGroup.spec.ts @@ -6,21 +6,21 @@ import { beforeCoderTest } from "../../hooks"; test.beforeEach(async ({ page }) => await beforeCoderTest(page)); test("remove group", async ({ page, baseURL }) => { - requiresEnterpriseLicense(); - await setupApiCalls(page); - const orgId = await getCurrentOrgId(); - const group = await createGroup(orgId); + requiresEnterpriseLicense(); + await setupApiCalls(page); + const orgId = await getCurrentOrgId(); + const group = await createGroup(orgId); - await page.goto(`${baseURL}/groups/${group.name}`, { - waitUntil: "domcontentloaded", - }); - await expect(page).toHaveTitle(`${group.display_name} - Coder`); + await page.goto(`${baseURL}/groups/${group.name}`, { + waitUntil: "domcontentloaded", + }); + await expect(page).toHaveTitle(`${group.display_name} - Coder`); - await page.getByRole("button", { name: "Delete" }).click(); - const dialog = page.getByTestId("dialog"); - await dialog.getByLabel("Name of the group to delete").fill(group.name); - await dialog.getByRole("button", { name: "Delete" }).click(); - await expect(page.getByText("Group deleted successfully.")).toBeVisible(); + await page.getByRole("button", { name: "Delete" }).click(); + const dialog = page.getByTestId("dialog"); + await dialog.getByLabel("Name of the group to delete").fill(group.name); + await dialog.getByRole("button", { name: "Delete" }).click(); + await expect(page.getByText("Group deleted successfully.")).toBeVisible(); - await expect(page).toHaveTitle("Groups - Coder"); + await expect(page).toHaveTitle("Groups - Coder"); }); diff --git a/site/e2e/tests/groups/removeMember.spec.ts b/site/e2e/tests/groups/removeMember.spec.ts index 716398b5fd..987b65a4aa 100644 --- a/site/e2e/tests/groups/removeMember.spec.ts +++ b/site/e2e/tests/groups/removeMember.spec.ts @@ -1,10 +1,10 @@ import { expect, test } from "@playwright/test"; import { API } from "api/api"; import { - createGroup, - createUser, - getCurrentOrgId, - setupApiCalls, + createGroup, + createUser, + getCurrentOrgId, + setupApiCalls, } from "../../api"; import { requiresEnterpriseLicense } from "../../helpers"; import { beforeCoderTest } from "../../hooks"; @@ -12,25 +12,25 @@ import { beforeCoderTest } from "../../hooks"; test.beforeEach(async ({ page }) => await beforeCoderTest(page)); test("remove member", async ({ page, baseURL }) => { - requiresEnterpriseLicense(); - await setupApiCalls(page); - const orgId = await getCurrentOrgId(); - const [group, member] = await Promise.all([ - createGroup(orgId), - createUser(orgId), - ]); - await API.addMember(group.id, member.id); + requiresEnterpriseLicense(); + await setupApiCalls(page); + const orgId = await getCurrentOrgId(); + const [group, member] = await Promise.all([ + createGroup(orgId), + createUser(orgId), + ]); + await API.addMember(group.id, member.id); - await page.goto(`${baseURL}/groups/${group.name}`, { - waitUntil: "domcontentloaded", - }); - await expect(page).toHaveTitle(`${group.display_name} - Coder`); + await page.goto(`${baseURL}/groups/${group.name}`, { + waitUntil: "domcontentloaded", + }); + await expect(page).toHaveTitle(`${group.display_name} - Coder`); - const userRow = page.getByRole("row", { name: member.username }); - await userRow.getByRole("button", { name: "More options" }).click(); + const userRow = page.getByRole("row", { name: member.username }); + await userRow.getByRole("button", { name: "More options" }).click(); - const menu = page.locator("#more-options"); - await menu.getByText("Remove").click({ timeout: 1_000 }); + const menu = page.locator("#more-options"); + await menu.getByText("Remove").click({ timeout: 1_000 }); - await expect(page.getByText("Member removed successfully.")).toBeVisible(); + await expect(page.getByText("Member removed successfully.")).toBeVisible(); }); diff --git a/site/e2e/tests/organizations.spec.ts b/site/e2e/tests/organizations.spec.ts index 1bb8f470bd..290368dd06 100644 --- a/site/e2e/tests/organizations.spec.ts +++ b/site/e2e/tests/organizations.spec.ts @@ -5,32 +5,32 @@ import { requiresEnterpriseLicense } from "../helpers"; import { beforeCoderTest } from "../hooks"; test.beforeEach(async ({ page }) => { - await beforeCoderTest(page); - await setupApiCalls(page); + await beforeCoderTest(page); + await setupApiCalls(page); }); test("create and delete organization", async ({ page, baseURL }) => { - requiresEnterpriseLicense(); + requiresEnterpriseLicense(); - // Create an organization - await page.goto(`${baseURL}/organizations/new`, { - waitUntil: "domcontentloaded", - }); + // Create an organization + await page.goto(`${baseURL}/organizations/new`, { + waitUntil: "domcontentloaded", + }); - await page.getByLabel("Name", { exact: true }).fill("floop"); - await page.getByLabel("Display name").fill("Floop"); - await page.getByLabel("Description").fill("Org description floop"); - await page.getByLabel("Icon", { exact: true }).fill("/emojis/1f957.png"); + await page.getByLabel("Name", { exact: true }).fill("floop"); + await page.getByLabel("Display name").fill("Floop"); + await page.getByLabel("Description").fill("Org description floop"); + await page.getByLabel("Icon", { exact: true }).fill("/emojis/1f957.png"); - await page.getByRole("button", { name: "Submit" }).click(); + await page.getByRole("button", { name: "Submit" }).click(); - // Expect to be redirected to the new organization - await expectUrl(page).toHavePathName("/organizations/floop"); - await expect(page.getByText("Organization created.")).toBeVisible(); + // Expect to be redirected to the new organization + await expectUrl(page).toHavePathName("/organizations/floop"); + await expect(page.getByText("Organization created.")).toBeVisible(); - await page.getByRole("button", { name: "Delete this organization" }).click(); - const dialog = page.getByTestId("dialog"); - await dialog.getByLabel("Name").fill("floop"); - await dialog.getByRole("button", { name: "Delete" }).click(); - await expect(page.getByText("Organization deleted.")).toBeVisible(); + await page.getByRole("button", { name: "Delete this organization" }).click(); + const dialog = page.getByTestId("dialog"); + await dialog.getByLabel("Name").fill("floop"); + await dialog.getByRole("button", { name: "Delete" }).click(); + await expect(page.getByText("Organization deleted.")).toBeVisible(); }); diff --git a/site/e2e/tests/outdatedAgent.spec.ts b/site/e2e/tests/outdatedAgent.spec.ts index 8603cea3d7..a4e42e62ec 100644 --- a/site/e2e/tests/outdatedAgent.spec.ts +++ b/site/e2e/tests/outdatedAgent.spec.ts @@ -1,13 +1,13 @@ import { randomUUID } from "node:crypto"; import { test } from "@playwright/test"; import { - createTemplate, - createWorkspace, - downloadCoderVersion, - sshIntoWorkspace, - startAgentWithCommand, - stopAgent, - stopWorkspace, + createTemplate, + createWorkspace, + downloadCoderVersion, + sshIntoWorkspace, + startAgentWithCommand, + stopAgent, + stopWorkspace, } from "../helpers"; import { beforeCoderTest } from "../hooks"; @@ -17,48 +17,48 @@ const agentVersion = "v2.12.1"; test.beforeEach(({ page }) => beforeCoderTest(page)); test(`ssh with agent ${agentVersion}`, async ({ page }) => { - test.setTimeout(40_000); // This is a slow test, 20s may not be enough on Mac. + test.setTimeout(40_000); // This is a slow test, 20s may not be enough on Mac. - const token = randomUUID(); - const template = await createTemplate(page, { - apply: [ - { - apply: { - resources: [ - { - agents: [ - { - token, - order: 0, - }, - ], - }, - ], - }, - }, - ], - }); - const workspaceName = await createWorkspace(page, template); - const binaryPath = await downloadCoderVersion(agentVersion); - const agent = await startAgentWithCommand(page, token, binaryPath); + const token = randomUUID(); + const template = await createTemplate(page, { + apply: [ + { + apply: { + resources: [ + { + agents: [ + { + token, + order: 0, + }, + ], + }, + ], + }, + }, + ], + }); + const workspaceName = await createWorkspace(page, template); + const binaryPath = await downloadCoderVersion(agentVersion); + const agent = await startAgentWithCommand(page, token, binaryPath); - const client = await sshIntoWorkspace(page, workspaceName); - await new Promise((resolve, reject) => { - // We just exec a command to be certain the agent is running! - client.exec("exit 0", (err, stream) => { - if (err) { - return reject(err); - } - stream.on("exit", (code) => { - if (code !== 0) { - return reject(new Error(`Command exited with code ${code}`)); - } - client.end(); - resolve(); - }); - }); - }); + const client = await sshIntoWorkspace(page, workspaceName); + await new Promise((resolve, reject) => { + // We just exec a command to be certain the agent is running! + client.exec("exit 0", (err, stream) => { + if (err) { + return reject(err); + } + stream.on("exit", (code) => { + if (code !== 0) { + return reject(new Error(`Command exited with code ${code}`)); + } + client.end(); + resolve(); + }); + }); + }); - await stopWorkspace(page, workspaceName); - await stopAgent(agent, false); + await stopWorkspace(page, workspaceName); + await stopAgent(agent, false); }); diff --git a/site/e2e/tests/outdatedCLI.spec.ts b/site/e2e/tests/outdatedCLI.spec.ts index 02c240ff1d..ccc5ba63e0 100644 --- a/site/e2e/tests/outdatedCLI.spec.ts +++ b/site/e2e/tests/outdatedCLI.spec.ts @@ -1,13 +1,13 @@ import { randomUUID } from "node:crypto"; import { test } from "@playwright/test"; import { - createTemplate, - createWorkspace, - downloadCoderVersion, - sshIntoWorkspace, - startAgent, - stopAgent, - stopWorkspace, + createTemplate, + createWorkspace, + downloadCoderVersion, + sshIntoWorkspace, + startAgent, + stopAgent, + stopWorkspace, } from "../helpers"; import { beforeCoderTest } from "../hooks"; @@ -17,46 +17,46 @@ const clientVersion = "v0.27.0"; test.beforeEach(({ page }) => beforeCoderTest(page)); test(`ssh with client ${clientVersion}`, async ({ page }) => { - const token = randomUUID(); - const template = await createTemplate(page, { - apply: [ - { - apply: { - resources: [ - { - agents: [ - { - token, - order: 0, - }, - ], - }, - ], - }, - }, - ], - }); - const workspaceName = await createWorkspace(page, template); - const agent = await startAgent(page, token); - const binaryPath = await downloadCoderVersion(clientVersion); + const token = randomUUID(); + const template = await createTemplate(page, { + apply: [ + { + apply: { + resources: [ + { + agents: [ + { + token, + order: 0, + }, + ], + }, + ], + }, + }, + ], + }); + const workspaceName = await createWorkspace(page, template); + const agent = await startAgent(page, token); + const binaryPath = await downloadCoderVersion(clientVersion); - const client = await sshIntoWorkspace(page, workspaceName, binaryPath); - await new Promise((resolve, reject) => { - // We just exec a command to be certain the agent is running! - client.exec("exit 0", (err, stream) => { - if (err) { - return reject(err); - } - stream.on("exit", (code) => { - if (code !== 0) { - return reject(new Error(`Command exited with code ${code}`)); - } - client.end(); - resolve(); - }); - }); - }); + const client = await sshIntoWorkspace(page, workspaceName, binaryPath); + await new Promise((resolve, reject) => { + // We just exec a command to be certain the agent is running! + client.exec("exit 0", (err, stream) => { + if (err) { + return reject(err); + } + stream.on("exit", (code) => { + if (code !== 0) { + return reject(new Error(`Command exited with code ${code}`)); + } + client.end(); + resolve(); + }); + }); + }); - await stopWorkspace(page, workspaceName); - await stopAgent(agent); + await stopWorkspace(page, workspaceName); + await stopAgent(agent); }); diff --git a/site/e2e/tests/templates/listTemplates.spec.ts b/site/e2e/tests/templates/listTemplates.spec.ts index 163bed4c94..ec69d1adfc 100644 --- a/site/e2e/tests/templates/listTemplates.spec.ts +++ b/site/e2e/tests/templates/listTemplates.spec.ts @@ -4,6 +4,6 @@ import { beforeCoderTest } from "../../hooks"; test.beforeEach(({ page }) => beforeCoderTest(page)); test("list templates", async ({ page, baseURL }) => { - await page.goto(`${baseURL}/templates`, { waitUntil: "domcontentloaded" }); - await expect(page).toHaveTitle("Templates - Coder"); + await page.goto(`${baseURL}/templates`, { waitUntil: "domcontentloaded" }); + await expect(page).toHaveTitle("Templates - Coder"); }); diff --git a/site/e2e/tests/templates/updateTemplateSchedule.spec.ts b/site/e2e/tests/templates/updateTemplateSchedule.spec.ts index 5678f015c9..a8380ab093 100644 --- a/site/e2e/tests/templates/updateTemplateSchedule.spec.ts +++ b/site/e2e/tests/templates/updateTemplateSchedule.spec.ts @@ -6,40 +6,40 @@ import { beforeCoderTest } from "../../hooks"; test.beforeEach(({ page }) => beforeCoderTest(page)); test("update template schedule settings without override other settings", async ({ - page, - baseURL, + page, + baseURL, }) => { - await setupApiCalls(page); - const orgId = await getCurrentOrgId(); - const templateVersion = await API.createTemplateVersion(orgId, { - storage_method: "file" as const, - provisioner: "echo", - user_variable_values: [], - example_id: "docker", - tags: {}, - }); - const template = await API.createTemplate(orgId, { - name: "test-template", - display_name: "Test Template", - template_version_id: templateVersion.id, - disable_everyone_group_access: false, - require_active_version: true, - }); + await setupApiCalls(page); + const orgId = await getCurrentOrgId(); + const templateVersion = await API.createTemplateVersion(orgId, { + storage_method: "file" as const, + provisioner: "echo", + user_variable_values: [], + example_id: "docker", + tags: {}, + }); + const template = await API.createTemplate(orgId, { + name: "test-template", + display_name: "Test Template", + template_version_id: templateVersion.id, + disable_everyone_group_access: false, + require_active_version: true, + }); - await page.goto(`${baseURL}/templates/${template.name}/settings/schedule`, { - waitUntil: "domcontentloaded", - }); - await page.getByLabel("Default autostop (hours)").fill("48"); - await page.getByRole("button", { name: "Submit" }).click(); - await expect(page.getByText("Template updated successfully")).toBeVisible(); + await page.goto(`${baseURL}/templates/${template.name}/settings/schedule`, { + waitUntil: "domcontentloaded", + }); + await page.getByLabel("Default autostop (hours)").fill("48"); + await page.getByRole("button", { name: "Submit" }).click(); + await expect(page.getByText("Template updated successfully")).toBeVisible(); - const updatedTemplate = await API.getTemplate(template.id); - // Validate that the template data remains consistent, with the exception of - // the 'default_ttl_ms' field (updated during the test) and the 'updated at' - // field (automatically updated by the backend). - expect({ - ...template, - default_ttl_ms: 48 * 60 * 60 * 1000, - updated_at: updatedTemplate.updated_at, - }).toStrictEqual(updatedTemplate); + const updatedTemplate = await API.getTemplate(template.id); + // Validate that the template data remains consistent, with the exception of + // the 'default_ttl_ms' field (updated during the test) and the 'updated at' + // field (automatically updated by the backend). + expect({ + ...template, + default_ttl_ms: 48 * 60 * 60 * 1000, + updated_at: updatedTemplate.updated_at, + }).toStrictEqual(updatedTemplate); }); diff --git a/site/e2e/tests/updateTemplate.spec.ts b/site/e2e/tests/updateTemplate.spec.ts index c35ebcd6d1..1480dd6a87 100644 --- a/site/e2e/tests/updateTemplate.spec.ts +++ b/site/e2e/tests/updateTemplate.spec.ts @@ -1,73 +1,73 @@ import { expect, test } from "@playwright/test"; import { expectUrl } from "../expectUrl"; import { - createGroup, - createTemplate, - requiresEnterpriseLicense, - updateTemplateSettings, + createGroup, + createTemplate, + requiresEnterpriseLicense, + updateTemplateSettings, } from "../helpers"; import { beforeCoderTest } from "../hooks"; test.beforeEach(({ page }) => beforeCoderTest(page)); test("template update with new name redirects on successful submit", async ({ - page, + page, }) => { - const templateName = await createTemplate(page); + const templateName = await createTemplate(page); - await updateTemplateSettings(page, templateName, { - name: "new-name", - }); + await updateTemplateSettings(page, templateName, { + name: "new-name", + }); }); test("add and remove a group", async ({ page }) => { - requiresEnterpriseLicense(); + requiresEnterpriseLicense(); - const templateName = await createTemplate(page); - const groupName = await createGroup(page); + const templateName = await createTemplate(page); + const groupName = await createGroup(page); - await page.goto(`/templates/${templateName}/settings/permissions`, { - waitUntil: "domcontentloaded", - }); - await expectUrl(page).toHavePathName( - `/templates/${templateName}/settings/permissions`, - ); + await page.goto(`/templates/${templateName}/settings/permissions`, { + waitUntil: "domcontentloaded", + }); + await expectUrl(page).toHavePathName( + `/templates/${templateName}/settings/permissions`, + ); - // Type the first half of the group name - await page - .getByPlaceholder("Search for user or group", { exact: true }) - .fill(groupName.slice(0, 4)); + // Type the first half of the group name + await page + .getByPlaceholder("Search for user or group", { exact: true }) + .fill(groupName.slice(0, 4)); - // Select the group from the list and add it - await page.getByText(groupName).click(); - await page.getByText("Add member").click(); - const row = page.locator(".MuiTableRow-root", { hasText: groupName }); - await expect(row).toBeVisible(); + // Select the group from the list and add it + await page.getByText(groupName).click(); + await page.getByText("Add member").click(); + const row = page.locator(".MuiTableRow-root", { hasText: groupName }); + await expect(row).toBeVisible(); - // Now remove the group - await row.getByLabel("More options").click(); - await page.getByText("Remove").click(); - await expect(page.getByText("Group removed successfully!")).toBeVisible(); - await expect(row).not.toBeVisible(); + // Now remove the group + await row.getByLabel("More options").click(); + await page.getByText("Remove").click(); + await expect(page.getByText("Group removed successfully!")).toBeVisible(); + await expect(row).not.toBeVisible(); }); test("require latest version", async ({ page }) => { - requiresEnterpriseLicense(); + requiresEnterpriseLicense(); - const templateName = await createTemplate(page); + const templateName = await createTemplate(page); - await page.goto(`/templates/${templateName}/settings`, { - waitUntil: "domcontentloaded", - }); - await expectUrl(page).toHavePathName(`/templates/${templateName}/settings`); - let checkbox = await page.waitForSelector("#require_active_version"); - await checkbox.click(); - await page.getByTestId("form-submit").click(); + await page.goto(`/templates/${templateName}/settings`, { + waitUntil: "domcontentloaded", + }); + await expectUrl(page).toHavePathName(`/templates/${templateName}/settings`); + let checkbox = await page.waitForSelector("#require_active_version"); + await checkbox.click(); + await page.getByTestId("form-submit").click(); - await page.goto(`/templates/${templateName}/settings`, { - waitUntil: "domcontentloaded", - }); - checkbox = await page.waitForSelector("#require_active_version"); - await checkbox.scrollIntoViewIfNeeded(); - expect(await checkbox.isChecked()).toBe(true); + await page.goto(`/templates/${templateName}/settings`, { + waitUntil: "domcontentloaded", + }); + checkbox = await page.waitForSelector("#require_active_version"); + await checkbox.scrollIntoViewIfNeeded(); + expect(await checkbox.isChecked()).toBe(true); }); diff --git a/site/e2e/tests/users/createUserWithPassword.spec.ts b/site/e2e/tests/users/createUserWithPassword.spec.ts index 077ef3a810..67f3ca92e9 100644 --- a/site/e2e/tests/users/createUserWithPassword.spec.ts +++ b/site/e2e/tests/users/createUserWithPassword.spec.ts @@ -5,63 +5,63 @@ import { beforeCoderTest } from "../../hooks"; test.beforeEach(async ({ page }) => await beforeCoderTest(page)); test("create user with password", async ({ page, baseURL }) => { - await page.goto(`${baseURL}/users`, { waitUntil: "domcontentloaded" }); - await expect(page).toHaveTitle("Users - Coder"); + await page.goto(`${baseURL}/users`, { waitUntil: "domcontentloaded" }); + await expect(page).toHaveTitle("Users - Coder"); - await page.getByRole("button", { name: "Create user" }).click(); - await expect(page).toHaveTitle("Create User - Coder"); + await page.getByRole("button", { name: "Create user" }).click(); + await expect(page).toHaveTitle("Create User - Coder"); - const name = randomName(); - const userValues = { - username: name, - name: name, - email: `${name}@coder.com`, - loginType: "password", - password: "s3cure&password!", - }; + const name = randomName(); + const userValues = { + username: name, + name: name, + email: `${name}@coder.com`, + loginType: "password", + password: "s3cure&password!", + }; - await page.getByLabel("Username").fill(userValues.username); - await page.getByLabel("Full name").fill(userValues.username); - await page.getByLabel("Email").fill(userValues.email); - await page.getByLabel("Login Type").click(); - await page.getByRole("option", { name: "Password", exact: false }).click(); - // Using input[name=password] due to the select element utilizing 'password' - // as the label for the currently active option. - const passwordField = page.locator("input[name=password]"); - await passwordField.fill(userValues.password); - await page.getByRole("button", { name: "Create user" }).click(); - await expect(page.getByText("Successfully created user.")).toBeVisible(); + await page.getByLabel("Username").fill(userValues.username); + await page.getByLabel("Full name").fill(userValues.username); + await page.getByLabel("Email").fill(userValues.email); + await page.getByLabel("Login Type").click(); + await page.getByRole("option", { name: "Password", exact: false }).click(); + // Using input[name=password] due to the select element utilizing 'password' + // as the label for the currently active option. + const passwordField = page.locator("input[name=password]"); + await passwordField.fill(userValues.password); + await page.getByRole("button", { name: "Create user" }).click(); + await expect(page.getByText("Successfully created user.")).toBeVisible(); - await expect(page).toHaveTitle("Users - Coder"); - await expect(page.locator("tr", { hasText: userValues.email })).toBeVisible(); + await expect(page).toHaveTitle("Users - Coder"); + await expect(page.locator("tr", { hasText: userValues.email })).toBeVisible(); }); test("create user without full name is optional", async ({ page, baseURL }) => { - await page.goto(`${baseURL}/users`, { waitUntil: "domcontentloaded" }); - await expect(page).toHaveTitle("Users - Coder"); + await page.goto(`${baseURL}/users`, { waitUntil: "domcontentloaded" }); + await expect(page).toHaveTitle("Users - Coder"); - await page.getByRole("button", { name: "Create user" }).click(); - await expect(page).toHaveTitle("Create User - Coder"); + await page.getByRole("button", { name: "Create user" }).click(); + await expect(page).toHaveTitle("Create User - Coder"); - const name = randomName(); - const userValues = { - username: name, - email: `${name}@coder.com`, - loginType: "password", - password: "s3cure&password!", - }; + const name = randomName(); + const userValues = { + username: name, + email: `${name}@coder.com`, + loginType: "password", + password: "s3cure&password!", + }; - await page.getByLabel("Username").fill(userValues.username); - await page.getByLabel("Email").fill(userValues.email); - await page.getByLabel("Login Type").click(); - await page.getByRole("option", { name: "Password", exact: false }).click(); - // Using input[name=password] due to the select element utilizing 'password' - // as the label for the currently active option. - const passwordField = page.locator("input[name=password]"); - await passwordField.fill(userValues.password); - await page.getByRole("button", { name: "Create user" }).click(); - await expect(page.getByText("Successfully created user.")).toBeVisible(); + await page.getByLabel("Username").fill(userValues.username); + await page.getByLabel("Email").fill(userValues.email); + await page.getByLabel("Login Type").click(); + await page.getByRole("option", { name: "Password", exact: false }).click(); + // Using input[name=password] due to the select element utilizing 'password' + // as the label for the currently active option. + const passwordField = page.locator("input[name=password]"); + await passwordField.fill(userValues.password); + await page.getByRole("button", { name: "Create user" }).click(); + await expect(page.getByText("Successfully created user.")).toBeVisible(); - await expect(page).toHaveTitle("Users - Coder"); - await expect(page.locator("tr", { hasText: userValues.email })).toBeVisible(); + await expect(page).toHaveTitle("Users - Coder"); + await expect(page.locator("tr", { hasText: userValues.email })).toBeVisible(); }); diff --git a/site/e2e/tests/users/removeUser.spec.ts b/site/e2e/tests/users/removeUser.spec.ts index 5dd47d7be8..f414d26b74 100644 --- a/site/e2e/tests/users/removeUser.spec.ts +++ b/site/e2e/tests/users/removeUser.spec.ts @@ -5,21 +5,21 @@ import { beforeCoderTest } from "../../hooks"; test.beforeEach(async ({ page }) => await beforeCoderTest(page)); test("remove user", async ({ page, baseURL }) => { - await setupApiCalls(page); - const orgId = await getCurrentOrgId(); - const user = await createUser(orgId); + await setupApiCalls(page); + const orgId = await getCurrentOrgId(); + const user = await createUser(orgId); - await page.goto(`${baseURL}/users`, { waitUntil: "domcontentloaded" }); - await expect(page).toHaveTitle("Users - Coder"); + await page.goto(`${baseURL}/users`, { waitUntil: "domcontentloaded" }); + await expect(page).toHaveTitle("Users - Coder"); - const userRow = page.getByRole("row", { name: user.email }); - await userRow.getByRole("button", { name: "More options" }).click(); - const menu = page.locator("#more-options"); - await menu.getByText("Delete").click(); + const userRow = page.getByRole("row", { name: user.email }); + await userRow.getByRole("button", { name: "More options" }).click(); + const menu = page.locator("#more-options"); + await menu.getByText("Delete").click(); - const dialog = page.getByTestId("dialog"); - await dialog.getByLabel("Name of the user to delete").fill(user.username); - await dialog.getByRole("button", { name: "Delete" }).click(); + const dialog = page.getByTestId("dialog"); + await dialog.getByLabel("Name of the user to delete").fill(user.username); + await dialog.getByRole("button", { name: "Delete" }).click(); - await expect(page.getByText("Successfully deleted the user.")).toBeVisible(); + await expect(page.getByText("Successfully deleted the user.")).toBeVisible(); }); diff --git a/site/e2e/tests/webTerminal.spec.ts b/site/e2e/tests/webTerminal.spec.ts index 28ae38a855..68a7620bde 100644 --- a/site/e2e/tests/webTerminal.spec.ts +++ b/site/e2e/tests/webTerminal.spec.ts @@ -1,71 +1,71 @@ import { randomUUID } from "node:crypto"; import { test } from "@playwright/test"; import { - createTemplate, - createWorkspace, - openTerminalWindow, - startAgent, - stopAgent, + createTemplate, + createWorkspace, + openTerminalWindow, + startAgent, + stopAgent, } from "../helpers"; import { beforeCoderTest } from "../hooks"; test.beforeEach(({ page }) => beforeCoderTest(page)); test("web terminal", async ({ context, page }) => { - const token = randomUUID(); - const template = await createTemplate(page, { - apply: [ - { - apply: { - resources: [ - { - agents: [ - { - token, - displayApps: { - webTerminal: true, - }, - order: 0, - }, - ], - }, - ], - }, - }, - ], - }); - const workspaceName = await createWorkspace(page, template); - const agent = await startAgent(page, token); - const terminal = await openTerminalWindow(page, context, workspaceName); + const token = randomUUID(); + const template = await createTemplate(page, { + apply: [ + { + apply: { + resources: [ + { + agents: [ + { + token, + displayApps: { + webTerminal: true, + }, + order: 0, + }, + ], + }, + ], + }, + }, + ], + }); + const workspaceName = await createWorkspace(page, template); + const agent = await startAgent(page, token); + const terminal = await openTerminalWindow(page, context, workspaceName); - await terminal.waitForSelector("div.xterm-rows", { - state: "visible", - }); + await terminal.waitForSelector("div.xterm-rows", { + state: "visible", + }); - // Workaround: delay next steps as "div.xterm-rows" can be recreated/reattached - // after a couple of milliseconds. - await terminal.waitForTimeout(2000); + // Workaround: delay next steps as "div.xterm-rows" can be recreated/reattached + // after a couple of milliseconds. + await terminal.waitForTimeout(2000); - // Ensure that we can type in it - await terminal.keyboard.type("echo he${justabreak}llo123456"); - await terminal.keyboard.press("Enter"); + // Ensure that we can type in it + await terminal.keyboard.type("echo he${justabreak}llo123456"); + await terminal.keyboard.press("Enter"); - // Check if "echo" command was executed - // try-catch is used temporarily to find the root cause: https://github.com/coder/coder/actions/runs/6176958762/job/16767089943 - try { - await terminal.waitForSelector( - 'div.xterm-rows span:text-matches("hello123456")', - { - state: "visible", - timeout: 10 * 1000, - }, - ); - } catch (error) { - const pageContent = await terminal.content(); - // eslint-disable-next-line no-console -- Let's see what is inside of xterm-rows - console.log("Unable to find echoed text:", pageContent); - throw error; - } + // Check if "echo" command was executed + // try-catch is used temporarily to find the root cause: https://github.com/coder/coder/actions/runs/6176958762/job/16767089943 + try { + await terminal.waitForSelector( + 'div.xterm-rows span:text-matches("hello123456")', + { + state: "visible", + timeout: 10 * 1000, + }, + ); + } catch (error) { + const pageContent = await terminal.content(); + // eslint-disable-next-line no-console -- Let's see what is inside of xterm-rows + console.log("Unable to find echoed text:", pageContent); + throw error; + } - await stopAgent(agent); + await stopAgent(agent); }); diff --git a/site/e2e/tests/workspaces/autoCreateWorkspace.spec.ts b/site/e2e/tests/workspaces/autoCreateWorkspace.spec.ts index 6a7fae146e..4bb052b4e8 100644 --- a/site/e2e/tests/workspaces/autoCreateWorkspace.spec.ts +++ b/site/e2e/tests/workspaces/autoCreateWorkspace.spec.ts @@ -1,65 +1,65 @@ import { expect, test } from "@playwright/test"; import { username } from "../../constants"; import { - createTemplate, - createWorkspace, - echoResponsesWithParameters, + createTemplate, + createWorkspace, + echoResponsesWithParameters, } from "../../helpers"; import { emptyParameter } from "../../parameters"; import type { RichParameter } from "../../provisionerGenerated"; test("create workspace in auto mode", async ({ page }) => { - const richParameters: RichParameter[] = [ - { ...emptyParameter, name: "repo", type: "string" }, - ]; - const template = await createTemplate( - page, - echoResponsesWithParameters(richParameters), - ); - const name = "test-workspace"; - await page.goto( - `/templates/${template}/workspace?mode=auto¶m.repo=example&name=${name}`, - { - waitUntil: "domcontentloaded", - }, - ); - await expect(page).toHaveTitle(`${username}/${name} - Coder`); + const richParameters: RichParameter[] = [ + { ...emptyParameter, name: "repo", type: "string" }, + ]; + const template = await createTemplate( + page, + echoResponsesWithParameters(richParameters), + ); + const name = "test-workspace"; + await page.goto( + `/templates/${template}/workspace?mode=auto¶m.repo=example&name=${name}`, + { + waitUntil: "domcontentloaded", + }, + ); + await expect(page).toHaveTitle(`${username}/${name} - Coder`); }); test("use an existing workspace that matches the `match` parameter instead of creating a new one", async ({ - page, + page, }) => { - const richParameters: RichParameter[] = [ - { ...emptyParameter, name: "repo", type: "string" }, - ]; - const template = await createTemplate( - page, - echoResponsesWithParameters(richParameters), - ); - const prevWorkspace = await createWorkspace(page, template); - await page.goto( - `/templates/${template}/workspace?mode=auto¶m.repo=example&name=new-name&match=name:${prevWorkspace}`, - { - waitUntil: "domcontentloaded", - }, - ); - await expect(page).toHaveTitle(`${username}/${prevWorkspace} - Coder`); + const richParameters: RichParameter[] = [ + { ...emptyParameter, name: "repo", type: "string" }, + ]; + const template = await createTemplate( + page, + echoResponsesWithParameters(richParameters), + ); + const prevWorkspace = await createWorkspace(page, template); + await page.goto( + `/templates/${template}/workspace?mode=auto¶m.repo=example&name=new-name&match=name:${prevWorkspace}`, + { + waitUntil: "domcontentloaded", + }, + ); + await expect(page).toHaveTitle(`${username}/${prevWorkspace} - Coder`); }); test("show error if `match` parameter is invalid", async ({ page }) => { - const richParameters: RichParameter[] = [ - { ...emptyParameter, name: "repo", type: "string" }, - ]; - const template = await createTemplate( - page, - echoResponsesWithParameters(richParameters), - ); - const prevWorkspace = await createWorkspace(page, template); - await page.goto( - `/templates/${template}/workspace?mode=auto¶m.repo=example&name=new-name&match=not-valid-query:${prevWorkspace}`, - { - waitUntil: "domcontentloaded", - }, - ); - await expect(page.getByText("Invalid match value")).toBeVisible(); + const richParameters: RichParameter[] = [ + { ...emptyParameter, name: "repo", type: "string" }, + ]; + const template = await createTemplate( + page, + echoResponsesWithParameters(richParameters), + ); + const prevWorkspace = await createWorkspace(page, template); + await page.goto( + `/templates/${template}/workspace?mode=auto¶m.repo=example&name=new-name&match=not-valid-query:${prevWorkspace}`, + { + waitUntil: "domcontentloaded", + }, + ); + await expect(page.getByText("Invalid match value")).toBeVisible(); }); diff --git a/site/e2e/tests/workspaces/createWorkspace.spec.ts b/site/e2e/tests/workspaces/createWorkspace.spec.ts index c00fa53980..372e9573fe 100644 --- a/site/e2e/tests/workspaces/createWorkspace.spec.ts +++ b/site/e2e/tests/workspaces/createWorkspace.spec.ts @@ -1,191 +1,191 @@ import { expect, test } from "@playwright/test"; import { - StarterTemplates, - createTemplate, - createWorkspace, - echoResponsesWithParameters, - openTerminalWindow, - requireTerraformProvisioner, - verifyParameters, + StarterTemplates, + createTemplate, + createWorkspace, + echoResponsesWithParameters, + openTerminalWindow, + requireTerraformProvisioner, + verifyParameters, } from "../../helpers"; import { beforeCoderTest } from "../../hooks"; import { - fifthParameter, - firstParameter, - fourthParameter, - randParamName, - secondParameter, - seventhParameter, - sixthParameter, - thirdParameter, + fifthParameter, + firstParameter, + fourthParameter, + randParamName, + secondParameter, + seventhParameter, + sixthParameter, + thirdParameter, } from "../../parameters"; import type { RichParameter } from "../../provisionerGenerated"; test.beforeEach(({ page }) => beforeCoderTest(page)); test("create workspace", async ({ page }) => { - const template = await createTemplate(page, { - apply: [ - { - apply: { - resources: [ - { - name: "example", - }, - ], - }, - }, - ], - }); - await createWorkspace(page, template); + const template = await createTemplate(page, { + apply: [ + { + apply: { + resources: [ + { + name: "example", + }, + ], + }, + }, + ], + }); + await createWorkspace(page, template); }); test("create workspace with default immutable parameters", async ({ page }) => { - const richParameters: RichParameter[] = [ - secondParameter, - fourthParameter, - fifthParameter, - ]; - const template = await createTemplate( - page, - echoResponsesWithParameters(richParameters), - ); - const workspaceName = await createWorkspace(page, template); - await verifyParameters(page, workspaceName, richParameters, [ - { name: secondParameter.name, value: secondParameter.defaultValue }, - { name: fourthParameter.name, value: fourthParameter.defaultValue }, - { name: fifthParameter.name, value: fifthParameter.defaultValue }, - ]); + const richParameters: RichParameter[] = [ + secondParameter, + fourthParameter, + fifthParameter, + ]; + const template = await createTemplate( + page, + echoResponsesWithParameters(richParameters), + ); + const workspaceName = await createWorkspace(page, template); + await verifyParameters(page, workspaceName, richParameters, [ + { name: secondParameter.name, value: secondParameter.defaultValue }, + { name: fourthParameter.name, value: fourthParameter.defaultValue }, + { name: fifthParameter.name, value: fifthParameter.defaultValue }, + ]); }); test("create workspace with default mutable parameters", async ({ page }) => { - const richParameters: RichParameter[] = [firstParameter, thirdParameter]; - const template = await createTemplate( - page, - echoResponsesWithParameters(richParameters), - ); - const workspaceName = await createWorkspace(page, template); - await verifyParameters(page, workspaceName, richParameters, [ - { name: firstParameter.name, value: firstParameter.defaultValue }, - { name: thirdParameter.name, value: thirdParameter.defaultValue }, - ]); + const richParameters: RichParameter[] = [firstParameter, thirdParameter]; + const template = await createTemplate( + page, + echoResponsesWithParameters(richParameters), + ); + const workspaceName = await createWorkspace(page, template); + await verifyParameters(page, workspaceName, richParameters, [ + { name: firstParameter.name, value: firstParameter.defaultValue }, + { name: thirdParameter.name, value: thirdParameter.defaultValue }, + ]); }); test("create workspace with default and required parameters", async ({ - page, + page, }) => { - const richParameters: RichParameter[] = [ - secondParameter, - fourthParameter, - sixthParameter, - seventhParameter, - ]; - const buildParameters = [ - { name: sixthParameter.name, value: "12345" }, - { name: seventhParameter.name, value: "abcdef" }, - ]; - const template = await createTemplate( - page, - echoResponsesWithParameters(richParameters), - ); - const workspaceName = await createWorkspace( - page, - template, - richParameters, - buildParameters, - ); - await verifyParameters(page, workspaceName, richParameters, [ - // user values: - ...buildParameters, - // default values: - { name: secondParameter.name, value: secondParameter.defaultValue }, - { name: fourthParameter.name, value: fourthParameter.defaultValue }, - ]); + const richParameters: RichParameter[] = [ + secondParameter, + fourthParameter, + sixthParameter, + seventhParameter, + ]; + const buildParameters = [ + { name: sixthParameter.name, value: "12345" }, + { name: seventhParameter.name, value: "abcdef" }, + ]; + const template = await createTemplate( + page, + echoResponsesWithParameters(richParameters), + ); + const workspaceName = await createWorkspace( + page, + template, + richParameters, + buildParameters, + ); + await verifyParameters(page, workspaceName, richParameters, [ + // user values: + ...buildParameters, + // default values: + { name: secondParameter.name, value: secondParameter.defaultValue }, + { name: fourthParameter.name, value: fourthParameter.defaultValue }, + ]); }); test("create workspace and overwrite default parameters", async ({ page }) => { - // We use randParamName to prevent the new values from corrupting user_history - // and thus affecting other tests. - const richParameters: RichParameter[] = [ - randParamName(secondParameter), - randParamName(fourthParameter), - ]; + // We use randParamName to prevent the new values from corrupting user_history + // and thus affecting other tests. + const richParameters: RichParameter[] = [ + randParamName(secondParameter), + randParamName(fourthParameter), + ]; - const buildParameters = [ - { name: richParameters[0].name, value: "AAAAA" }, - { name: richParameters[1].name, value: "false" }, - ]; - const template = await createTemplate( - page, - echoResponsesWithParameters(richParameters), - ); + const buildParameters = [ + { name: richParameters[0].name, value: "AAAAA" }, + { name: richParameters[1].name, value: "false" }, + ]; + const template = await createTemplate( + page, + echoResponsesWithParameters(richParameters), + ); - const workspaceName = await createWorkspace( - page, - template, - richParameters, - buildParameters, - ); - await verifyParameters(page, workspaceName, richParameters, buildParameters); + const workspaceName = await createWorkspace( + page, + template, + richParameters, + buildParameters, + ); + await verifyParameters(page, workspaceName, richParameters, buildParameters); }); test("create workspace with disable_param search params", async ({ page }) => { - const richParameters: RichParameter[] = [ - firstParameter, // mutable - secondParameter, //immutable - ]; + const richParameters: RichParameter[] = [ + firstParameter, // mutable + secondParameter, //immutable + ]; - const templateName = await createTemplate( - page, - echoResponsesWithParameters(richParameters), - ); + const templateName = await createTemplate( + page, + echoResponsesWithParameters(richParameters), + ); - await page.goto( - `/templates/${templateName}/workspace?disable_params=first_parameter,second_parameter`, - { - waitUntil: "domcontentloaded", - }, - ); + await page.goto( + `/templates/${templateName}/workspace?disable_params=first_parameter,second_parameter`, + { + waitUntil: "domcontentloaded", + }, + ); - await expect(page.getByLabel(/First parameter/i)).toBeDisabled(); - await expect(page.getByLabel(/Second parameter/i)).toBeDisabled(); + await expect(page.getByLabel(/First parameter/i)).toBeDisabled(); + await expect(page.getByLabel(/Second parameter/i)).toBeDisabled(); }); test("create docker workspace", async ({ context, page }) => { - test.skip( - true, - "creating docker containers is currently leaky. They are not cleaned up when the tests are over.", - ); - requireTerraformProvisioner(); - const template = await createTemplate(page, StarterTemplates.STARTER_DOCKER); + test.skip( + true, + "creating docker containers is currently leaky. They are not cleaned up when the tests are over.", + ); + requireTerraformProvisioner(); + const template = await createTemplate(page, StarterTemplates.STARTER_DOCKER); - const workspaceName = await createWorkspace(page, template); + const workspaceName = await createWorkspace(page, template); - // The workspace agents must be ready before we try to interact with the workspace. - await page.waitForSelector( - `//div[@role="status"][@data-testid="agent-status-ready"]`, - { - state: "visible", - }, - ); + // The workspace agents must be ready before we try to interact with the workspace. + await page.waitForSelector( + `//div[@role="status"][@data-testid="agent-status-ready"]`, + { + state: "visible", + }, + ); - // Wait for the terminal button to be visible, and click it. - const terminalButton = - "//a[@data-testid='terminal'][normalize-space()='Terminal']"; - await page.waitForSelector(terminalButton, { - state: "visible", - }); + // Wait for the terminal button to be visible, and click it. + const terminalButton = + "//a[@data-testid='terminal'][normalize-space()='Terminal']"; + await page.waitForSelector(terminalButton, { + state: "visible", + }); - const terminal = await openTerminalWindow( - page, - context, - workspaceName, - "main", - ); - await terminal.waitForSelector( - `//textarea[contains(@class,"xterm-helper-textarea")]`, - { - state: "visible", - }, - ); + const terminal = await openTerminalWindow( + page, + context, + workspaceName, + "main", + ); + await terminal.waitForSelector( + `//textarea[contains(@class,"xterm-helper-textarea")]`, + { + state: "visible", + }, + ); }); diff --git a/site/e2e/tests/workspaces/restartWorkspace.spec.ts b/site/e2e/tests/workspaces/restartWorkspace.spec.ts index 9b45ffe337..36fbb6bc9a 100644 --- a/site/e2e/tests/workspaces/restartWorkspace.spec.ts +++ b/site/e2e/tests/workspaces/restartWorkspace.spec.ts @@ -1,10 +1,10 @@ import { test } from "@playwright/test"; import { - buildWorkspaceWithParameters, - createTemplate, - createWorkspace, - echoResponsesWithParameters, - verifyParameters, + buildWorkspaceWithParameters, + createTemplate, + createWorkspace, + echoResponsesWithParameters, + verifyParameters, } from "../../helpers"; import { beforeCoderTest } from "../../hooks"; import { firstBuildOption, secondBuildOption } from "../../parameters"; @@ -13,35 +13,35 @@ import type { RichParameter } from "../../provisionerGenerated"; test.beforeEach(({ page }) => beforeCoderTest(page)); test("restart workspace with ephemeral parameters", async ({ page }) => { - const richParameters: RichParameter[] = [firstBuildOption, secondBuildOption]; - const template = await createTemplate( - page, - echoResponsesWithParameters(richParameters), - ); - const workspaceName = await createWorkspace(page, template); + const richParameters: RichParameter[] = [firstBuildOption, secondBuildOption]; + const template = await createTemplate( + page, + echoResponsesWithParameters(richParameters), + ); + const workspaceName = await createWorkspace(page, template); - // Verify that build options are default (not selected). - await verifyParameters(page, workspaceName, richParameters, [ - { name: richParameters[0].name, value: firstBuildOption.defaultValue }, - { name: richParameters[1].name, value: secondBuildOption.defaultValue }, - ]); + // Verify that build options are default (not selected). + await verifyParameters(page, workspaceName, richParameters, [ + { name: richParameters[0].name, value: firstBuildOption.defaultValue }, + { name: richParameters[1].name, value: secondBuildOption.defaultValue }, + ]); - // Now, restart the workspace with ephemeral parameters selected. - const buildParameters = [ - { name: richParameters[0].name, value: "AAAAA" }, - { name: richParameters[1].name, value: "true" }, - ]; - await buildWorkspaceWithParameters( - page, - workspaceName, - richParameters, - buildParameters, - true, - ); + // Now, restart the workspace with ephemeral parameters selected. + const buildParameters = [ + { name: richParameters[0].name, value: "AAAAA" }, + { name: richParameters[1].name, value: "true" }, + ]; + await buildWorkspaceWithParameters( + page, + workspaceName, + richParameters, + buildParameters, + true, + ); - // Verify that build options are default (not selected). - await verifyParameters(page, workspaceName, richParameters, [ - { name: richParameters[0].name, value: firstBuildOption.defaultValue }, - { name: richParameters[1].name, value: secondBuildOption.defaultValue }, - ]); + // Verify that build options are default (not selected). + await verifyParameters(page, workspaceName, richParameters, [ + { name: richParameters[0].name, value: firstBuildOption.defaultValue }, + { name: richParameters[1].name, value: secondBuildOption.defaultValue }, + ]); }); diff --git a/site/e2e/tests/workspaces/startWorkspace.spec.ts b/site/e2e/tests/workspaces/startWorkspace.spec.ts index 37f4766558..684525130f 100644 --- a/site/e2e/tests/workspaces/startWorkspace.spec.ts +++ b/site/e2e/tests/workspaces/startWorkspace.spec.ts @@ -1,11 +1,11 @@ import { test } from "@playwright/test"; import { - buildWorkspaceWithParameters, - createTemplate, - createWorkspace, - echoResponsesWithParameters, - stopWorkspace, - verifyParameters, + buildWorkspaceWithParameters, + createTemplate, + createWorkspace, + echoResponsesWithParameters, + stopWorkspace, + verifyParameters, } from "../../helpers"; import { beforeCoderTest } from "../../hooks"; import { firstBuildOption, secondBuildOption } from "../../parameters"; @@ -14,38 +14,38 @@ import type { RichParameter } from "../../provisionerGenerated"; test.beforeEach(({ page }) => beforeCoderTest(page)); test("start workspace with ephemeral parameters", async ({ page }) => { - const richParameters: RichParameter[] = [firstBuildOption, secondBuildOption]; - const template = await createTemplate( - page, - echoResponsesWithParameters(richParameters), - ); - const workspaceName = await createWorkspace(page, template); + const richParameters: RichParameter[] = [firstBuildOption, secondBuildOption]; + const template = await createTemplate( + page, + echoResponsesWithParameters(richParameters), + ); + const workspaceName = await createWorkspace(page, template); - // Verify that build options are default (not selected). - await verifyParameters(page, workspaceName, richParameters, [ - { name: richParameters[0].name, value: firstBuildOption.defaultValue }, - { name: richParameters[1].name, value: secondBuildOption.defaultValue }, - ]); + // Verify that build options are default (not selected). + await verifyParameters(page, workspaceName, richParameters, [ + { name: richParameters[0].name, value: firstBuildOption.defaultValue }, + { name: richParameters[1].name, value: secondBuildOption.defaultValue }, + ]); - // Stop the workspace - await stopWorkspace(page, workspaceName); + // Stop the workspace + await stopWorkspace(page, workspaceName); - // Now, start the workspace with ephemeral parameters selected. - const buildParameters = [ - { name: richParameters[0].name, value: "AAAAA" }, - { name: richParameters[1].name, value: "true" }, - ]; + // Now, start the workspace with ephemeral parameters selected. + const buildParameters = [ + { name: richParameters[0].name, value: "AAAAA" }, + { name: richParameters[1].name, value: "true" }, + ]; - await buildWorkspaceWithParameters( - page, - workspaceName, - richParameters, - buildParameters, - ); + await buildWorkspaceWithParameters( + page, + workspaceName, + richParameters, + buildParameters, + ); - // Verify that build options are default (not selected). - await verifyParameters(page, workspaceName, richParameters, [ - { name: richParameters[0].name, value: firstBuildOption.defaultValue }, - { name: richParameters[1].name, value: secondBuildOption.defaultValue }, - ]); + // Verify that build options are default (not selected). + await verifyParameters(page, workspaceName, richParameters, [ + { name: richParameters[0].name, value: firstBuildOption.defaultValue }, + { name: richParameters[1].name, value: secondBuildOption.defaultValue }, + ]); }); diff --git a/site/e2e/tests/workspaces/updateWorkspace.spec.ts b/site/e2e/tests/workspaces/updateWorkspace.spec.ts index 2d09b3e616..8ff256f74d 100644 --- a/site/e2e/tests/workspaces/updateWorkspace.spec.ts +++ b/site/e2e/tests/workspaces/updateWorkspace.spec.ts @@ -1,132 +1,132 @@ import { test } from "@playwright/test"; import { - createTemplate, - createWorkspace, - echoResponsesWithParameters, - updateTemplate, - updateWorkspace, - updateWorkspaceParameters, - verifyParameters, + createTemplate, + createWorkspace, + echoResponsesWithParameters, + updateTemplate, + updateWorkspace, + updateWorkspaceParameters, + verifyParameters, } from "../../helpers"; import { beforeCoderTest } from "../../hooks"; import { - fifthParameter, - firstParameter, - secondBuildOption, - secondParameter, - sixthParameter, + fifthParameter, + firstParameter, + secondBuildOption, + secondParameter, + sixthParameter, } from "../../parameters"; import type { RichParameter } from "../../provisionerGenerated"; test.beforeEach(({ page }) => beforeCoderTest(page)); test("update workspace, new optional, immutable parameter added", async ({ - page, + page, }) => { - const richParameters: RichParameter[] = [firstParameter, secondParameter]; - const template = await createTemplate( - page, - echoResponsesWithParameters(richParameters), - ); + const richParameters: RichParameter[] = [firstParameter, secondParameter]; + const template = await createTemplate( + page, + echoResponsesWithParameters(richParameters), + ); - const workspaceName = await createWorkspace(page, template); + const workspaceName = await createWorkspace(page, template); - // Verify that parameter values are default. - await verifyParameters(page, workspaceName, richParameters, [ - { name: firstParameter.name, value: firstParameter.defaultValue }, - { name: secondParameter.name, value: secondParameter.defaultValue }, - ]); + // Verify that parameter values are default. + await verifyParameters(page, workspaceName, richParameters, [ + { name: firstParameter.name, value: firstParameter.defaultValue }, + { name: secondParameter.name, value: secondParameter.defaultValue }, + ]); - // Push updated template. - const updatedRichParameters = [...richParameters, fifthParameter]; - await updateTemplate( - page, - template, - echoResponsesWithParameters(updatedRichParameters), - ); + // Push updated template. + const updatedRichParameters = [...richParameters, fifthParameter]; + await updateTemplate( + page, + template, + echoResponsesWithParameters(updatedRichParameters), + ); - // Now, update the workspace, and select the value for immutable parameter. - await updateWorkspace(page, workspaceName, updatedRichParameters, [ - { name: fifthParameter.name, value: fifthParameter.options[0].value }, - ]); + // Now, update the workspace, and select the value for immutable parameter. + await updateWorkspace(page, workspaceName, updatedRichParameters, [ + { name: fifthParameter.name, value: fifthParameter.options[0].value }, + ]); - // Verify parameter values. - await verifyParameters(page, workspaceName, updatedRichParameters, [ - { name: firstParameter.name, value: firstParameter.defaultValue }, - { name: secondParameter.name, value: secondParameter.defaultValue }, - { name: fifthParameter.name, value: fifthParameter.options[0].value }, - ]); + // Verify parameter values. + await verifyParameters(page, workspaceName, updatedRichParameters, [ + { name: firstParameter.name, value: firstParameter.defaultValue }, + { name: secondParameter.name, value: secondParameter.defaultValue }, + { name: fifthParameter.name, value: fifthParameter.options[0].value }, + ]); }); test("update workspace, new required, mutable parameter added", async ({ - page, + page, }) => { - const richParameters: RichParameter[] = [firstParameter, secondParameter]; - const template = await createTemplate( - page, - echoResponsesWithParameters(richParameters), - ); + const richParameters: RichParameter[] = [firstParameter, secondParameter]; + const template = await createTemplate( + page, + echoResponsesWithParameters(richParameters), + ); - const workspaceName = await createWorkspace(page, template); + const workspaceName = await createWorkspace(page, template); - // Verify that parameter values are default. - await verifyParameters(page, workspaceName, richParameters, [ - { name: firstParameter.name, value: firstParameter.defaultValue }, - { name: secondParameter.name, value: secondParameter.defaultValue }, - ]); + // Verify that parameter values are default. + await verifyParameters(page, workspaceName, richParameters, [ + { name: firstParameter.name, value: firstParameter.defaultValue }, + { name: secondParameter.name, value: secondParameter.defaultValue }, + ]); - // Push updated template. - const updatedRichParameters = [...richParameters, sixthParameter]; - await updateTemplate( - page, - template, - echoResponsesWithParameters(updatedRichParameters), - ); + // Push updated template. + const updatedRichParameters = [...richParameters, sixthParameter]; + await updateTemplate( + page, + template, + echoResponsesWithParameters(updatedRichParameters), + ); - // Now, update the workspace, and provide the parameter value. - const buildParameters = [{ name: sixthParameter.name, value: "99" }]; - await updateWorkspace( - page, - workspaceName, - updatedRichParameters, - buildParameters, - ); + // Now, update the workspace, and provide the parameter value. + const buildParameters = [{ name: sixthParameter.name, value: "99" }]; + await updateWorkspace( + page, + workspaceName, + updatedRichParameters, + buildParameters, + ); - // Verify parameter values. - await verifyParameters(page, workspaceName, updatedRichParameters, [ - { name: firstParameter.name, value: firstParameter.defaultValue }, - { name: secondParameter.name, value: secondParameter.defaultValue }, - ...buildParameters, - ]); + // Verify parameter values. + await verifyParameters(page, workspaceName, updatedRichParameters, [ + { name: firstParameter.name, value: firstParameter.defaultValue }, + { name: secondParameter.name, value: secondParameter.defaultValue }, + ...buildParameters, + ]); }); test("update workspace with ephemeral parameter enabled", async ({ page }) => { - const richParameters: RichParameter[] = [firstParameter, secondBuildOption]; - const template = await createTemplate( - page, - echoResponsesWithParameters(richParameters), - ); + const richParameters: RichParameter[] = [firstParameter, secondBuildOption]; + const template = await createTemplate( + page, + echoResponsesWithParameters(richParameters), + ); - const workspaceName = await createWorkspace(page, template); + const workspaceName = await createWorkspace(page, template); - // Verify that parameter values are default. - await verifyParameters(page, workspaceName, richParameters, [ - { name: firstParameter.name, value: firstParameter.defaultValue }, - { name: secondBuildOption.name, value: secondBuildOption.defaultValue }, - ]); + // Verify that parameter values are default. + await verifyParameters(page, workspaceName, richParameters, [ + { name: firstParameter.name, value: firstParameter.defaultValue }, + { name: secondBuildOption.name, value: secondBuildOption.defaultValue }, + ]); - // Now, update the workspace, and select the value for ephemeral parameter. - const buildParameters = [{ name: secondBuildOption.name, value: "true" }]; - await updateWorkspaceParameters( - page, - workspaceName, - richParameters, - buildParameters, - ); + // Now, update the workspace, and select the value for ephemeral parameter. + const buildParameters = [{ name: secondBuildOption.name, value: "true" }]; + await updateWorkspaceParameters( + page, + workspaceName, + richParameters, + buildParameters, + ); - // Verify that parameter values are default. - await verifyParameters(page, workspaceName, richParameters, [ - { name: firstParameter.name, value: firstParameter.defaultValue }, - { name: secondBuildOption.name, value: secondBuildOption.defaultValue }, - ]); + // Verify that parameter values are default. + await verifyParameters(page, workspaceName, richParameters, [ + { name: firstParameter.name, value: firstParameter.defaultValue }, + { name: secondBuildOption.name, value: secondBuildOption.defaultValue }, + ]); }); diff --git a/site/src/@types/emoji-mart.d.ts b/site/src/@types/emoji-mart.d.ts index 6d13bf6e2c..4d00a551a4 100644 --- a/site/src/@types/emoji-mart.d.ts +++ b/site/src/@types/emoji-mart.d.ts @@ -1,44 +1,44 @@ declare module "@emoji-mart/react" { - interface CustomCategory { - id: string; - name: string; - emojis: CustomEmoji[]; - } + interface CustomCategory { + id: string; + name: string; + emojis: CustomEmoji[]; + } - interface CustomEmoji { - id: string; - name: string; - keywords: string[]; - skins: CustomEmojiSkin[]; - } + interface CustomEmoji { + id: string; + name: string; + keywords: string[]; + skins: CustomEmojiSkin[]; + } - interface CustomEmojiSkin { - src: string; - } + interface CustomEmojiSkin { + src: string; + } - type EmojiData = EmojiResource & { - id: string; - keywords: string[]; - name: string; - native?: string; - shortcodes: string; - }; + type EmojiData = EmojiResource & { + id: string; + keywords: string[]; + name: string; + native?: string; + shortcodes: string; + }; - type EmojiResource = - | { unified: undefined; src: string } - | { unified: string; src: undefined }; + type EmojiResource = + | { unified: undefined; src: string } + | { unified: string; src: undefined }; - export interface EmojiMartProps { - set: "native" | "apple" | "facebook" | "google" | "twitter"; - theme: "dark" | "light"; - data: unknown; - custom: CustomCategory[]; - emojiButtonSize?: number; - emojiSize?: number; - onEmojiSelect: (emoji: EmojiData) => void; - } + export interface EmojiMartProps { + set: "native" | "apple" | "facebook" | "google" | "twitter"; + theme: "dark" | "light"; + data: unknown; + custom: CustomCategory[]; + emojiButtonSize?: number; + emojiSize?: number; + onEmojiSelect: (emoji: EmojiData) => void; + } - const EmojiMart: React.FC; + const EmojiMart: React.FC; - export default EmojiMart; + export default EmojiMart; } diff --git a/site/src/@types/emotion.d.ts b/site/src/@types/emotion.d.ts index 57123a0796..ec423cc27c 100644 --- a/site/src/@types/emotion.d.ts +++ b/site/src/@types/emotion.d.ts @@ -1,5 +1,5 @@ import type { Theme as CoderTheme } from "theme"; declare module "@emotion/react" { - interface Theme extends CoderTheme {} + interface Theme extends CoderTheme {} } diff --git a/site/src/@types/mui.d.ts b/site/src/@types/mui.d.ts index 2b4478c4a5..a1b4b61b07 100644 --- a/site/src/@types/mui.d.ts +++ b/site/src/@types/mui.d.ts @@ -2,29 +2,29 @@ import type { PaletteColor, PaletteColorOptions } from "@mui/material/styles"; declare module "@mui/material/styles" { - interface Palette { - neutral: PaletteColor; - dots: string; - } + interface Palette { + neutral: PaletteColor; + dots: string; + } - interface PaletteOptions { - neutral?: PaletteColorOptions; - dots?: string; - } + interface PaletteOptions { + neutral?: PaletteColorOptions; + dots?: string; + } } declare module "@mui/material/Button" { - interface ButtonPropsColorOverrides { - neutral: true; - } + interface ButtonPropsColorOverrides { + neutral: true; + } - interface ButtonPropsSizeOverrides { - xlarge: true; - } + interface ButtonPropsSizeOverrides { + xlarge: true; + } } declare module "@mui/material/Checkbox" { - interface CheckboxPropsSizeOverrides { - xsmall: true; - } + interface CheckboxPropsSizeOverrides { + xsmall: true; + } } diff --git a/site/src/@types/storybook.d.ts b/site/src/@types/storybook.d.ts index a44fe0b329..2c4674ed15 100644 --- a/site/src/@types/storybook.d.ts +++ b/site/src/@types/storybook.d.ts @@ -1,26 +1,26 @@ import * as _storybook_types from "@storybook/react"; import type { - DeploymentValues, - Experiments, - FeatureName, - SerpentOption, - User, + DeploymentValues, + Experiments, + FeatureName, + SerpentOption, + User, } from "api/typesGenerated"; import type { Permissions } from "contexts/auth/permissions"; import type { QueryKey } from "react-query"; declare module "@storybook/react" { - type WebSocketEvent = - | { event: "message"; data: string } - | { event: "error" | "close" }; - interface Parameters { - features?: FeatureName[]; - experiments?: Experiments; - queries?: { key: QueryKey; data: unknown }[]; - webSocket?: WebSocketEvent[]; - user?: User; - permissions?: Partial; - deploymentValues?: DeploymentValues; - deploymentOptions?: SerpentOption[]; - } + type WebSocketEvent = + | { event: "message"; data: string } + | { event: "error" | "close" }; + interface Parameters { + features?: FeatureName[]; + experiments?: Experiments; + queries?: { key: QueryKey; data: unknown }[]; + webSocket?: WebSocketEvent[]; + user?: User; + permissions?: Partial; + deploymentValues?: DeploymentValues; + deploymentOptions?: SerpentOption[]; + } } diff --git a/site/src/App.tsx b/site/src/App.tsx index 582e86da37..56cd193029 100644 --- a/site/src/App.tsx +++ b/site/src/App.tsx @@ -1,11 +1,11 @@ import "./theme/globalFonts"; import { ReactQueryDevtools } from "@tanstack/react-query-devtools"; import { - type FC, - type ReactNode, - StrictMode, - useEffect, - useState, + type FC, + type ReactNode, + StrictMode, + useEffect, + useState, } from "react"; import { HelmetProvider } from "react-helmet-async"; import { QueryClient, QueryClientProvider } from "react-query"; @@ -17,75 +17,75 @@ import { AuthProvider } from "./contexts/auth/AuthProvider"; import { router } from "./router"; const defaultQueryClient = new QueryClient({ - defaultOptions: { - queries: { - retry: false, - refetchOnWindowFocus: false, - }, - }, + defaultOptions: { + queries: { + retry: false, + refetchOnWindowFocus: false, + }, + }, }); interface AppProvidersProps { - children: ReactNode; - queryClient?: QueryClient; + children: ReactNode; + queryClient?: QueryClient; } // extending the global window interface so we can conditionally // show our react query devtools declare global { - interface Window { - toggleDevtools: () => void; - } + interface Window { + toggleDevtools: () => void; + } } export const AppProviders: FC = ({ - children, - queryClient = defaultQueryClient, + children, + queryClient = defaultQueryClient, }) => { - // https://tanstack.com/query/v4/docs/react/devtools - const [showDevtools, setShowDevtools] = useState(false); + // https://tanstack.com/query/v4/docs/react/devtools + const [showDevtools, setShowDevtools] = useState(false); - useEffect(() => { - // Storing key in variable to avoid accidental typos; we're working with the - // window object, so there's basically zero type-checking available - const toggleKey = "toggleDevtools"; + useEffect(() => { + // Storing key in variable to avoid accidental typos; we're working with the + // window object, so there's basically zero type-checking available + const toggleKey = "toggleDevtools"; - // Don't want to throw away the previous devtools value if some other - // extension added something already - const devtoolsBeforeSync = window[toggleKey]; - window[toggleKey] = () => { - devtoolsBeforeSync?.(); - setShowDevtools((current) => !current); - }; + // Don't want to throw away the previous devtools value if some other + // extension added something already + const devtoolsBeforeSync = window[toggleKey]; + window[toggleKey] = () => { + devtoolsBeforeSync?.(); + setShowDevtools((current) => !current); + }; - return () => { - window[toggleKey] = devtoolsBeforeSync; - }; - }, []); + return () => { + window[toggleKey] = devtoolsBeforeSync; + }; + }, []); - return ( - - - - - {children} - - - - {showDevtools && } - - - ); + return ( + + + + + {children} + + + + {showDevtools && } + + + ); }; export const App: FC = () => { - return ( - - - - - - - - ); + return ( + + + + + + + + ); }; diff --git a/site/src/__mocks__/monaco-editor.ts b/site/src/__mocks__/monaco-editor.ts index dad85000f6..6b71646560 100644 --- a/site/src/__mocks__/monaco-editor.ts +++ b/site/src/__mocks__/monaco-editor.ts @@ -1,18 +1,18 @@ const editor = { - defineTheme: () => { - // - }, - create: () => { - return { - dispose: () => { - // - }, - }; - }, + defineTheme: () => { + // + }, + create: () => { + return { + dispose: () => { + // + }, + }; + }, }; const monaco = { - editor, + editor, }; module.exports = monaco; diff --git a/site/src/__mocks__/react-markdown.tsx b/site/src/__mocks__/react-markdown.tsx index 1d2f3dad03..de1d2ea4d2 100644 --- a/site/src/__mocks__/react-markdown.tsx +++ b/site/src/__mocks__/react-markdown.tsx @@ -1,7 +1,7 @@ import type { FC, PropsWithChildren } from "react"; const ReactMarkdown: FC = ({ children }) => { - return
{children}
; + return
{children}
; }; export default ReactMarkdown; diff --git a/site/src/api/api.test.ts b/site/src/api/api.test.ts index 49b4c6748d..e72dd5f8d0 100644 --- a/site/src/api/api.test.ts +++ b/site/src/api/api.test.ts @@ -1,10 +1,10 @@ import { - MockTemplate, - MockTemplateVersionParameter1, - MockTemplateVersionParameter2, - MockWorkspace, - MockWorkspaceBuild, - MockWorkspaceBuildParameter1, + MockTemplate, + MockTemplateVersionParameter1, + MockTemplateVersionParameter2, + MockWorkspace, + MockWorkspaceBuild, + MockWorkspaceBuildParameter1, } from "testHelpers/entities"; import { API, MissingBuildParameters, getURLWithSearchParams } from "./api"; import type * as TypesGen from "./typesGenerated"; @@ -12,225 +12,225 @@ import type * as TypesGen from "./typesGenerated"; const axiosInstance = API.getAxiosInstance(); describe("api.ts", () => { - describe("login", () => { - it("should return LoginResponse", async () => { - // given - const loginResponse: TypesGen.LoginWithPasswordResponse = { - session_token: "abc_123_test", - }; + describe("login", () => { + it("should return LoginResponse", async () => { + // given + const loginResponse: TypesGen.LoginWithPasswordResponse = { + session_token: "abc_123_test", + }; - jest - .spyOn(axiosInstance, "post") - .mockResolvedValueOnce({ data: loginResponse }); + jest + .spyOn(axiosInstance, "post") + .mockResolvedValueOnce({ data: loginResponse }); - // when - const result = await API.login("test", "123"); + // when + const result = await API.login("test", "123"); - // then - expect(axiosInstance.post).toHaveBeenCalled(); - expect(result).toStrictEqual(loginResponse); - }); + // then + expect(axiosInstance.post).toHaveBeenCalled(); + expect(result).toStrictEqual(loginResponse); + }); - it("should throw an error on 401", async () => { - // given - // ..ensure that we await our expect assertion in async/await test - expect.assertions(1); - const expectedError = { - message: "Validation failed", - errors: [{ field: "email", code: "email" }], - }; - const axiosMockPost = jest.fn().mockImplementationOnce(() => { - return Promise.reject(expectedError); - }); - axiosInstance.post = axiosMockPost; + it("should throw an error on 401", async () => { + // given + // ..ensure that we await our expect assertion in async/await test + expect.assertions(1); + const expectedError = { + message: "Validation failed", + errors: [{ field: "email", code: "email" }], + }; + const axiosMockPost = jest.fn().mockImplementationOnce(() => { + return Promise.reject(expectedError); + }); + axiosInstance.post = axiosMockPost; - try { - await API.login("test", "123"); - } catch (error) { - expect(error).toStrictEqual(expectedError); - } - }); - }); + try { + await API.login("test", "123"); + } catch (error) { + expect(error).toStrictEqual(expectedError); + } + }); + }); - describe("logout", () => { - it("should return without erroring", async () => { - // given - const axiosMockPost = jest.fn().mockImplementationOnce(() => { - return Promise.resolve(); - }); - axiosInstance.post = axiosMockPost; + describe("logout", () => { + it("should return without erroring", async () => { + // given + const axiosMockPost = jest.fn().mockImplementationOnce(() => { + return Promise.resolve(); + }); + axiosInstance.post = axiosMockPost; - // when - await API.logout(); + // when + await API.logout(); - // then - expect(axiosMockPost).toHaveBeenCalled(); - }); + // then + expect(axiosMockPost).toHaveBeenCalled(); + }); - it("should throw an error on 500", async () => { - // given - // ..ensure that we await our expect assertion in async/await test - expect.assertions(1); - const expectedError = { - message: "Failed to logout.", - }; - const axiosMockPost = jest.fn().mockImplementationOnce(() => { - return Promise.reject(expectedError); - }); + it("should throw an error on 500", async () => { + // given + // ..ensure that we await our expect assertion in async/await test + expect.assertions(1); + const expectedError = { + message: "Failed to logout.", + }; + const axiosMockPost = jest.fn().mockImplementationOnce(() => { + return Promise.reject(expectedError); + }); - axiosInstance.post = axiosMockPost; + axiosInstance.post = axiosMockPost; - try { - await API.logout(); - } catch (error) { - expect(error).toStrictEqual(expectedError); - } - }); - }); + try { + await API.logout(); + } catch (error) { + expect(error).toStrictEqual(expectedError); + } + }); + }); - describe("getApiKey", () => { - it("should return APIKeyResponse", async () => { - // given - const apiKeyResponse: TypesGen.GenerateAPIKeyResponse = { - key: "abc_123_test", - }; - const axiosMockPost = jest.fn().mockImplementationOnce(() => { - return Promise.resolve({ data: apiKeyResponse }); - }); + describe("getApiKey", () => { + it("should return APIKeyResponse", async () => { + // given + const apiKeyResponse: TypesGen.GenerateAPIKeyResponse = { + key: "abc_123_test", + }; + const axiosMockPost = jest.fn().mockImplementationOnce(() => { + return Promise.resolve({ data: apiKeyResponse }); + }); - axiosInstance.post = axiosMockPost; + axiosInstance.post = axiosMockPost; - // when - const result = await API.getApiKey(); + // when + const result = await API.getApiKey(); - // then - expect(axiosMockPost).toHaveBeenCalled(); - expect(result).toStrictEqual(apiKeyResponse); - }); + // then + expect(axiosMockPost).toHaveBeenCalled(); + expect(result).toStrictEqual(apiKeyResponse); + }); - it("should throw an error on 401", async () => { - // given - // ..ensure that we await our expect assertion in async/await test - expect.assertions(1); - const expectedError = { - message: "No Cookie!", - }; - const axiosMockPost = jest.fn().mockImplementationOnce(() => { - return Promise.reject(expectedError); - }); + it("should throw an error on 401", async () => { + // given + // ..ensure that we await our expect assertion in async/await test + expect.assertions(1); + const expectedError = { + message: "No Cookie!", + }; + const axiosMockPost = jest.fn().mockImplementationOnce(() => { + return Promise.reject(expectedError); + }); - axiosInstance.post = axiosMockPost; + axiosInstance.post = axiosMockPost; - try { - await API.getApiKey(); - } catch (error) { - expect(error).toStrictEqual(expectedError); - } - }); - }); + try { + await API.getApiKey(); + } catch (error) { + expect(error).toStrictEqual(expectedError); + } + }); + }); - describe("getURLWithSearchParams - workspaces", () => { - it.each<[string, TypesGen.WorkspaceFilter | undefined, string]>([ - ["/api/v2/workspaces", undefined, "/api/v2/workspaces"], + describe("getURLWithSearchParams - workspaces", () => { + it.each<[string, TypesGen.WorkspaceFilter | undefined, string]>([ + ["/api/v2/workspaces", undefined, "/api/v2/workspaces"], - ["/api/v2/workspaces", { q: "" }, "/api/v2/workspaces"], - [ - "/api/v2/workspaces", - { q: "owner:1" }, - "/api/v2/workspaces?q=owner%3A1", - ], + ["/api/v2/workspaces", { q: "" }, "/api/v2/workspaces"], + [ + "/api/v2/workspaces", + { q: "owner:1" }, + "/api/v2/workspaces?q=owner%3A1", + ], - [ - "/api/v2/workspaces", - { q: "owner:me" }, - "/api/v2/workspaces?q=owner%3Ame", - ], - ])( - "Workspaces - getURLWithSearchParams(%p, %p) returns %p", - (basePath, filter, expected) => { - expect(getURLWithSearchParams(basePath, filter)).toBe(expected); - }, - ); - }); + [ + "/api/v2/workspaces", + { q: "owner:me" }, + "/api/v2/workspaces?q=owner%3Ame", + ], + ])( + "Workspaces - getURLWithSearchParams(%p, %p) returns %p", + (basePath, filter, expected) => { + expect(getURLWithSearchParams(basePath, filter)).toBe(expected); + }, + ); + }); - describe("getURLWithSearchParams - users", () => { - it.each<[string, TypesGen.UsersRequest | undefined, string]>([ - ["/api/v2/users", undefined, "/api/v2/users"], - [ - "/api/v2/users", - { q: "status:active" }, - "/api/v2/users?q=status%3Aactive", - ], - ["/api/v2/users", { q: "" }, "/api/v2/users"], - ])( - "Users - getURLWithSearchParams(%p, %p) returns %p", - (basePath, filter, expected) => { - expect(getURLWithSearchParams(basePath, filter)).toBe(expected); - }, - ); - }); + describe("getURLWithSearchParams - users", () => { + it.each<[string, TypesGen.UsersRequest | undefined, string]>([ + ["/api/v2/users", undefined, "/api/v2/users"], + [ + "/api/v2/users", + { q: "status:active" }, + "/api/v2/users?q=status%3Aactive", + ], + ["/api/v2/users", { q: "" }, "/api/v2/users"], + ])( + "Users - getURLWithSearchParams(%p, %p) returns %p", + (basePath, filter, expected) => { + expect(getURLWithSearchParams(basePath, filter)).toBe(expected); + }, + ); + }); - describe("update", () => { - it("creates a build with start and the latest template", async () => { - jest - .spyOn(API, "postWorkspaceBuild") - .mockResolvedValueOnce(MockWorkspaceBuild); - jest.spyOn(API, "getTemplate").mockResolvedValueOnce(MockTemplate); - await API.updateWorkspace(MockWorkspace); - expect(API.postWorkspaceBuild).toHaveBeenCalledWith(MockWorkspace.id, { - transition: "start", - template_version_id: MockTemplate.active_version_id, - rich_parameter_values: [], - }); - }); + describe("update", () => { + it("creates a build with start and the latest template", async () => { + jest + .spyOn(API, "postWorkspaceBuild") + .mockResolvedValueOnce(MockWorkspaceBuild); + jest.spyOn(API, "getTemplate").mockResolvedValueOnce(MockTemplate); + await API.updateWorkspace(MockWorkspace); + expect(API.postWorkspaceBuild).toHaveBeenCalledWith(MockWorkspace.id, { + transition: "start", + template_version_id: MockTemplate.active_version_id, + rich_parameter_values: [], + }); + }); - it("fails when having missing parameters", async () => { - jest - .spyOn(API, "postWorkspaceBuild") - .mockResolvedValue(MockWorkspaceBuild); - jest.spyOn(API, "getTemplate").mockResolvedValue(MockTemplate); - jest.spyOn(API, "getWorkspaceBuildParameters").mockResolvedValue([]); - jest - .spyOn(API, "getTemplateVersionRichParameters") - .mockResolvedValue([ - MockTemplateVersionParameter1, - { ...MockTemplateVersionParameter2, mutable: false }, - ]); + it("fails when having missing parameters", async () => { + jest + .spyOn(API, "postWorkspaceBuild") + .mockResolvedValue(MockWorkspaceBuild); + jest.spyOn(API, "getTemplate").mockResolvedValue(MockTemplate); + jest.spyOn(API, "getWorkspaceBuildParameters").mockResolvedValue([]); + jest + .spyOn(API, "getTemplateVersionRichParameters") + .mockResolvedValue([ + MockTemplateVersionParameter1, + { ...MockTemplateVersionParameter2, mutable: false }, + ]); - let error = new Error(); - try { - await API.updateWorkspace(MockWorkspace); - } catch (e) { - error = e as Error; - } + let error = new Error(); + try { + await API.updateWorkspace(MockWorkspace); + } catch (e) { + error = e as Error; + } - expect(error).toBeInstanceOf(MissingBuildParameters); - // Verify if the correct missing parameters are being passed - expect((error as MissingBuildParameters).parameters).toEqual([ - MockTemplateVersionParameter1, - { ...MockTemplateVersionParameter2, mutable: false }, - ]); - }); + expect(error).toBeInstanceOf(MissingBuildParameters); + // Verify if the correct missing parameters are being passed + expect((error as MissingBuildParameters).parameters).toEqual([ + MockTemplateVersionParameter1, + { ...MockTemplateVersionParameter2, mutable: false }, + ]); + }); - it("creates a build with the no parameters if it is already filled", async () => { - jest - .spyOn(API, "postWorkspaceBuild") - .mockResolvedValueOnce(MockWorkspaceBuild); - jest.spyOn(API, "getTemplate").mockResolvedValueOnce(MockTemplate); - jest - .spyOn(API, "getWorkspaceBuildParameters") - .mockResolvedValue([MockWorkspaceBuildParameter1]); - jest - .spyOn(API, "getTemplateVersionRichParameters") - .mockResolvedValue([ - { ...MockTemplateVersionParameter1, required: true, mutable: false }, - ]); - await API.updateWorkspace(MockWorkspace); - expect(API.postWorkspaceBuild).toHaveBeenCalledWith(MockWorkspace.id, { - transition: "start", - template_version_id: MockTemplate.active_version_id, - rich_parameter_values: [], - }); - }); - }); + it("creates a build with the no parameters if it is already filled", async () => { + jest + .spyOn(API, "postWorkspaceBuild") + .mockResolvedValueOnce(MockWorkspaceBuild); + jest.spyOn(API, "getTemplate").mockResolvedValueOnce(MockTemplate); + jest + .spyOn(API, "getWorkspaceBuildParameters") + .mockResolvedValue([MockWorkspaceBuildParameter1]); + jest + .spyOn(API, "getTemplateVersionRichParameters") + .mockResolvedValue([ + { ...MockTemplateVersionParameter1, required: true, mutable: false }, + ]); + await API.updateWorkspace(MockWorkspace); + expect(API.postWorkspaceBuild).toHaveBeenCalledWith(MockWorkspace.id, { + transition: "start", + template_version_id: MockTemplate.active_version_id, + rich_parameter_values: [], + }); + }); + }); }); diff --git a/site/src/api/api.ts b/site/src/api/api.ts index 0d7225ec90..456607bf3d 100644 --- a/site/src/api/api.ts +++ b/site/src/api/api.ts @@ -27,77 +27,77 @@ import * as TypesGen from "./typesGenerated"; import type { PostWorkspaceUsageRequest } from "./typesGenerated"; const getMissingParameters = ( - oldBuildParameters: TypesGen.WorkspaceBuildParameter[], - newBuildParameters: TypesGen.WorkspaceBuildParameter[], - templateParameters: TypesGen.TemplateVersionParameter[], + oldBuildParameters: TypesGen.WorkspaceBuildParameter[], + newBuildParameters: TypesGen.WorkspaceBuildParameter[], + templateParameters: TypesGen.TemplateVersionParameter[], ) => { - const missingParameters: TypesGen.TemplateVersionParameter[] = []; - const requiredParameters: TypesGen.TemplateVersionParameter[] = []; + const missingParameters: TypesGen.TemplateVersionParameter[] = []; + const requiredParameters: TypesGen.TemplateVersionParameter[] = []; - for (const p of templateParameters) { - // It is mutable and required. Mutable values can be changed after so we - // don't need to ask them if they are not required. - const isMutableAndRequired = p.mutable && p.required; - // Is immutable, so we can check if it is its first time on the build - const isImmutable = !p.mutable; + for (const p of templateParameters) { + // It is mutable and required. Mutable values can be changed after so we + // don't need to ask them if they are not required. + const isMutableAndRequired = p.mutable && p.required; + // Is immutable, so we can check if it is its first time on the build + const isImmutable = !p.mutable; - if (isMutableAndRequired || isImmutable) { - requiredParameters.push(p); - } - } + if (isMutableAndRequired || isImmutable) { + requiredParameters.push(p); + } + } - for (const parameter of requiredParameters) { - // Check if there is a new value - let buildParameter = newBuildParameters.find( - (p) => p.name === parameter.name, - ); + for (const parameter of requiredParameters) { + // Check if there is a new value + let buildParameter = newBuildParameters.find( + (p) => p.name === parameter.name, + ); - // If not, get the old one - if (!buildParameter) { - buildParameter = oldBuildParameters.find( - (p) => p.name === parameter.name, - ); - } + // If not, get the old one + if (!buildParameter) { + buildParameter = oldBuildParameters.find( + (p) => p.name === parameter.name, + ); + } - // If there is a value from the new or old one, it is not missed - if (buildParameter) { - continue; - } + // If there is a value from the new or old one, it is not missed + if (buildParameter) { + continue; + } - missingParameters.push(parameter); - } + missingParameters.push(parameter); + } - // Check if parameter "options" changed and we can't use old build parameters. - for (const templateParameter of templateParameters) { - if (templateParameter.options.length === 0) { - continue; - } + // Check if parameter "options" changed and we can't use old build parameters. + for (const templateParameter of templateParameters) { + if (templateParameter.options.length === 0) { + continue; + } - // Check if there is a new value - let buildParameter = newBuildParameters.find( - (p) => p.name === templateParameter.name, - ); + // Check if there is a new value + let buildParameter = newBuildParameters.find( + (p) => p.name === templateParameter.name, + ); - // If not, get the old one - if (!buildParameter) { - buildParameter = oldBuildParameters.find( - (p) => p.name === templateParameter.name, - ); - } + // If not, get the old one + if (!buildParameter) { + buildParameter = oldBuildParameters.find( + (p) => p.name === templateParameter.name, + ); + } - if (!buildParameter) { - continue; - } + if (!buildParameter) { + continue; + } - const matchingOption = templateParameter.options.find( - (option) => option.value === buildParameter?.value, - ); - if (!matchingOption) { - missingParameters.push(templateParameter); - } - } + const matchingOption = templateParameter.options.find( + (option) => option.value === buildParameter?.value, + ); + if (!matchingOption) { + missingParameters.push(templateParameter); + } + } - return missingParameters; + return missingParameters; }; /** @@ -107,10 +107,10 @@ const getMissingParameters = ( * (ServerSentEvent) */ export const watchAgentMetadata = (agentId: string): EventSource => { - return new EventSource( - `${location.protocol}//${location.host}/api/v2/workspaceagents/${agentId}/watch-metadata`, - { withCredentials: true }, - ); + return new EventSource( + `${location.protocol}//${location.host}/api/v2/workspaceagents/${agentId}/watch-metadata`, + { withCredentials: true }, + ); }; /** @@ -118,273 +118,273 @@ export const watchAgentMetadata = (agentId: string): EventSource => { * (ServerSentEvent) */ export const watchWorkspace = (workspaceId: string): EventSource => { - return new EventSource( - `${location.protocol}//${location.host}/api/v2/workspaces/${workspaceId}/watch`, - { withCredentials: true }, - ); + return new EventSource( + `${location.protocol}//${location.host}/api/v2/workspaces/${workspaceId}/watch`, + { withCredentials: true }, + ); }; export const getURLWithSearchParams = ( - basePath: string, - options?: SearchParamOptions, + basePath: string, + options?: SearchParamOptions, ): string => { - if (!options) { - return basePath; - } + if (!options) { + return basePath; + } - const searchParams = new URLSearchParams(); - for (const [key, value] of Object.entries(options)) { - if (value !== undefined && value !== "") { - searchParams.append(key, value.toString()); - } - } + const searchParams = new URLSearchParams(); + for (const [key, value] of Object.entries(options)) { + if (value !== undefined && value !== "") { + searchParams.append(key, value.toString()); + } + } - const searchString = searchParams.toString(); - return searchString ? `${basePath}?${searchString}` : basePath; + const searchString = searchParams.toString(); + return searchString ? `${basePath}?${searchString}` : basePath; }; // withDefaultFeatures sets all unspecified features to not_entitled and // disabled. export const withDefaultFeatures = ( - fs: Partial, + fs: Partial, ): TypesGen.Entitlements["features"] => { - for (const feature of TypesGen.FeatureNames) { - // Skip fields that are already filled. - if (fs[feature] !== undefined) { - continue; - } + for (const feature of TypesGen.FeatureNames) { + // Skip fields that are already filled. + if (fs[feature] !== undefined) { + continue; + } - fs[feature] = { - enabled: false, - entitlement: "not_entitled", - }; - } + fs[feature] = { + enabled: false, + entitlement: "not_entitled", + }; + } - return fs as TypesGen.Entitlements["features"]; + return fs as TypesGen.Entitlements["features"]; }; type WatchBuildLogsByTemplateVersionIdOptions = { - after?: number; - onMessage: (log: TypesGen.ProvisionerJobLog) => void; - onDone?: () => void; - onError: (error: Error) => void; + after?: number; + onMessage: (log: TypesGen.ProvisionerJobLog) => void; + onDone?: () => void; + onError: (error: Error) => void; }; export const watchBuildLogsByTemplateVersionId = ( - versionId: string, - { - onMessage, - onDone, - onError, - after, - }: WatchBuildLogsByTemplateVersionIdOptions, + versionId: string, + { + onMessage, + onDone, + onError, + after, + }: WatchBuildLogsByTemplateVersionIdOptions, ) => { - const searchParams = new URLSearchParams({ follow: "true" }); - if (after !== undefined) { - searchParams.append("after", after.toString()); - } + const searchParams = new URLSearchParams({ follow: "true" }); + if (after !== undefined) { + searchParams.append("after", after.toString()); + } - const proto = location.protocol === "https:" ? "wss:" : "ws:"; - const socket = new WebSocket( - `${proto}//${ - location.host - }/api/v2/templateversions/${versionId}/logs?${searchParams.toString()}`, - ); + const proto = location.protocol === "https:" ? "wss:" : "ws:"; + const socket = new WebSocket( + `${proto}//${ + location.host + }/api/v2/templateversions/${versionId}/logs?${searchParams.toString()}`, + ); - socket.binaryType = "blob"; + socket.binaryType = "blob"; - socket.addEventListener("message", (event) => - onMessage(JSON.parse(event.data) as TypesGen.ProvisionerJobLog), - ); + socket.addEventListener("message", (event) => + onMessage(JSON.parse(event.data) as TypesGen.ProvisionerJobLog), + ); - socket.addEventListener("error", () => { - onError(new Error("Connection for logs failed.")); - socket.close(); - }); + socket.addEventListener("error", () => { + onError(new Error("Connection for logs failed.")); + socket.close(); + }); - socket.addEventListener("close", () => { - // When the socket closes, logs have finished streaming! - onDone?.(); - }); + socket.addEventListener("close", () => { + // When the socket closes, logs have finished streaming! + onDone?.(); + }); - return socket; + return socket; }; export const watchWorkspaceAgentLogs = ( - agentId: string, - { after, onMessage, onDone, onError }: WatchWorkspaceAgentLogsOptions, + agentId: string, + { after, onMessage, onDone, onError }: WatchWorkspaceAgentLogsOptions, ) => { - // WebSocket compression in Safari (confirmed in 16.5) is broken when - // the server sends large messages. The following error is seen: - // - // WebSocket connection to 'wss://.../logs?follow&after=0' failed: The operation couldn’t be completed. Protocol error - // - const noCompression = - userAgentParser(navigator.userAgent).browser.name === "Safari" - ? "&no_compression" - : ""; + // WebSocket compression in Safari (confirmed in 16.5) is broken when + // the server sends large messages. The following error is seen: + // + // WebSocket connection to 'wss://.../logs?follow&after=0' failed: The operation couldn’t be completed. Protocol error + // + const noCompression = + userAgentParser(navigator.userAgent).browser.name === "Safari" + ? "&no_compression" + : ""; - const proto = location.protocol === "https:" ? "wss:" : "ws:"; - const socket = new WebSocket( - `${proto}//${location.host}/api/v2/workspaceagents/${agentId}/logs?follow&after=${after}${noCompression}`, - ); - socket.binaryType = "blob"; + const proto = location.protocol === "https:" ? "wss:" : "ws:"; + const socket = new WebSocket( + `${proto}//${location.host}/api/v2/workspaceagents/${agentId}/logs?follow&after=${after}${noCompression}`, + ); + socket.binaryType = "blob"; - socket.addEventListener("message", (event) => { - const logs = JSON.parse(event.data) as TypesGen.WorkspaceAgentLog[]; - onMessage(logs); - }); + socket.addEventListener("message", (event) => { + const logs = JSON.parse(event.data) as TypesGen.WorkspaceAgentLog[]; + onMessage(logs); + }); - socket.addEventListener("error", () => { - onError(new Error("socket errored")); - }); + socket.addEventListener("error", () => { + onError(new Error("socket errored")); + }); - socket.addEventListener("close", () => { - onDone?.(); - }); + socket.addEventListener("close", () => { + onDone?.(); + }); - return socket; + return socket; }; type WatchWorkspaceAgentLogsOptions = { - after: number; - onMessage: (logs: TypesGen.WorkspaceAgentLog[]) => void; - onDone?: () => void; - onError: (error: Error) => void; + after: number; + onMessage: (logs: TypesGen.WorkspaceAgentLog[]) => void; + onDone?: () => void; + onError: (error: Error) => void; }; type WatchBuildLogsByBuildIdOptions = { - after?: number; - onMessage: (log: TypesGen.ProvisionerJobLog) => void; - onDone?: () => void; - onError?: (error: Error) => void; + after?: number; + onMessage: (log: TypesGen.ProvisionerJobLog) => void; + onDone?: () => void; + onError?: (error: Error) => void; }; export const watchBuildLogsByBuildId = ( - buildId: string, - { onMessage, onDone, onError, after }: WatchBuildLogsByBuildIdOptions, + buildId: string, + { onMessage, onDone, onError, after }: WatchBuildLogsByBuildIdOptions, ) => { - const searchParams = new URLSearchParams({ follow: "true" }); - if (after !== undefined) { - searchParams.append("after", after.toString()); - } - const proto = location.protocol === "https:" ? "wss:" : "ws:"; - const socket = new WebSocket( - `${proto}//${ - location.host - }/api/v2/workspacebuilds/${buildId}/logs?${searchParams.toString()}`, - ); - socket.binaryType = "blob"; + const searchParams = new URLSearchParams({ follow: "true" }); + if (after !== undefined) { + searchParams.append("after", after.toString()); + } + const proto = location.protocol === "https:" ? "wss:" : "ws:"; + const socket = new WebSocket( + `${proto}//${ + location.host + }/api/v2/workspacebuilds/${buildId}/logs?${searchParams.toString()}`, + ); + socket.binaryType = "blob"; - socket.addEventListener("message", (event) => - onMessage(JSON.parse(event.data) as TypesGen.ProvisionerJobLog), - ); + socket.addEventListener("message", (event) => + onMessage(JSON.parse(event.data) as TypesGen.ProvisionerJobLog), + ); - socket.addEventListener("error", () => { - onError?.(new Error("Connection for logs failed.")); - socket.close(); - }); + socket.addEventListener("error", () => { + onError?.(new Error("Connection for logs failed.")); + socket.close(); + }); - socket.addEventListener("close", () => { - // When the socket closes, logs have finished streaming! - onDone?.(); - }); + socket.addEventListener("close", () => { + // When the socket closes, logs have finished streaming! + onDone?.(); + }); - return socket; + return socket; }; // This is the base header that is used for several requests. This is defined as // a readonly value, but only copies of it should be passed into the API calls, // because Axios is able to mutate the headers const BASE_CONTENT_TYPE_JSON = { - "Content-Type": "application/json", + "Content-Type": "application/json", } as const satisfies HeadersInit; export type GetTemplatesOptions = Readonly<{ - readonly deprecated?: boolean; + readonly deprecated?: boolean; }>; export type GetTemplatesQuery = Readonly<{ - readonly q: string; + readonly q: string; }>; function normalizeGetTemplatesOptions( - options: GetTemplatesOptions | GetTemplatesQuery = {}, + options: GetTemplatesOptions | GetTemplatesQuery = {}, ): Record { - if ("q" in options) { - return options; - } + if ("q" in options) { + return options; + } - const params: Record = {}; - if (options.deprecated !== undefined) { - params.deprecated = String(options.deprecated); - } - return params; + const params: Record = {}; + if (options.deprecated !== undefined) { + params.deprecated = String(options.deprecated); + } + return params; } type SearchParamOptions = TypesGen.Pagination & { - q?: string; + q?: string; }; type RestartWorkspaceParameters = Readonly<{ - workspace: TypesGen.Workspace; - buildParameters?: TypesGen.WorkspaceBuildParameter[]; + workspace: TypesGen.Workspace; + buildParameters?: TypesGen.WorkspaceBuildParameter[]; }>; export type DeleteWorkspaceOptions = Pick< - TypesGen.CreateWorkspaceBuildRequest, - "log_level" | "orphan" + TypesGen.CreateWorkspaceBuildRequest, + "log_level" | "orphan" >; export type DeploymentConfig = Readonly<{ - config: TypesGen.DeploymentValues; - options: TypesGen.SerpentOption[]; + config: TypesGen.DeploymentValues; + options: TypesGen.SerpentOption[]; }>; type Claims = { - license_expires: number; - account_type?: string; - account_id?: string; - trial: boolean; - all_features: boolean; - // feature_set is omitted on legacy licenses - feature_set?: string; - version: number; - features: Record; - require_telemetry?: boolean; + license_expires: number; + account_type?: string; + account_id?: string; + trial: boolean; + all_features: boolean; + // feature_set is omitted on legacy licenses + feature_set?: string; + version: number; + features: Record; + require_telemetry?: boolean; }; export type GetLicensesResponse = Omit & { - claims: Claims; - expires_at: string; + claims: Claims; + expires_at: string; }; export type InsightsParams = { - start_time: string; - end_time: string; - template_ids: string; + start_time: string; + end_time: string; + template_ids: string; }; export type InsightsTemplateParams = InsightsParams & { - interval: "day" | "week"; + interval: "day" | "week"; }; export type GetJFrogXRayScanParams = { - workspaceId: string; - agentId: string; + workspaceId: string; + agentId: string; }; export class MissingBuildParameters extends Error { - parameters: TypesGen.TemplateVersionParameter[] = []; - versionId: string; + parameters: TypesGen.TemplateVersionParameter[] = []; + versionId: string; - constructor( - parameters: TypesGen.TemplateVersionParameter[], - versionId: string, - ) { - super("Missing build parameters."); - this.parameters = parameters; - this.versionId = versionId; - } + constructor( + parameters: TypesGen.TemplateVersionParameter[], + versionId: string, + ) { + super("Missing build parameters."); + this.parameters = parameters; + this.versionId = versionId; + } } /** @@ -401,1720 +401,1720 @@ export class MissingBuildParameters extends Error { * lexical scope. */ class ApiMethods { - constructor(protected readonly axios: AxiosInstance) {} - - login = async ( - email: string, - password: string, - ): Promise => { - const payload = JSON.stringify({ email, password }); - const response = await this.axios.post( - "/api/v2/users/login", - payload, - { headers: { ...BASE_CONTENT_TYPE_JSON } }, - ); - - return response.data; - }; - - convertToOAUTH = async (request: TypesGen.ConvertLoginRequest) => { - const response = await this.axios.post( - "/api/v2/users/me/convert-login", - request, - ); - - return response.data; - }; - - logout = async (): Promise => { - return this.axios.post("/api/v2/users/logout"); - }; - - getAuthenticatedUser = async () => { - const response = await this.axios.get("/api/v2/users/me"); - return response.data; - }; - - getUserParameters = async (templateID: string) => { - const response = await this.axios.get( - `/api/v2/users/me/autofill-parameters?template_id=${templateID}`, - ); - - return response.data; - }; - - getAuthMethods = async (): Promise => { - const response = await this.axios.get( - "/api/v2/users/authmethods", - ); - - return response.data; - }; - - getUserLoginType = async (): Promise => { - const response = await this.axios.get( - "/api/v2/users/me/login-type", - ); - - return response.data; - }; - - checkAuthorization = async ( - params: TypesGen.AuthorizationRequest, - ): Promise => { - const response = await this.axios.post( - "/api/v2/authcheck", - params, - ); - - return response.data; - }; - - getApiKey = async (): Promise => { - const response = await this.axios.post( - "/api/v2/users/me/keys", - ); - - return response.data; - }; - - getTokens = async ( - params: TypesGen.TokensFilter, - ): Promise => { - const response = await this.axios.get( - "/api/v2/users/me/keys/tokens", - { params }, - ); - - return response.data; - }; - - deleteToken = async (keyId: string): Promise => { - await this.axios.delete(`/api/v2/users/me/keys/${keyId}`); - }; - - createToken = async ( - params: TypesGen.CreateTokenRequest, - ): Promise => { - const response = await this.axios.post( - "/api/v2/users/me/keys/tokens", - params, - ); - - return response.data; - }; - - getTokenConfig = async (): Promise => { - const response = await this.axios.get( - "/api/v2/users/me/keys/tokens/tokenconfig", - ); - - return response.data; - }; - - getUsers = async ( - options: TypesGen.UsersRequest, - signal?: AbortSignal, - ): Promise => { - const url = getURLWithSearchParams("/api/v2/users", options); - const response = await this.axios.get( - url.toString(), - { signal }, - ); - - return response.data; - }; - - createOrganization = async (params: TypesGen.CreateOrganizationRequest) => { - const response = await this.axios.post( - "/api/v2/organizations", - params, - ); - return response.data; - }; - - /** - * @param organization Can be the organization's ID or name - */ - updateOrganization = async ( - organization: string, - params: TypesGen.UpdateOrganizationRequest, - ) => { - const response = await this.axios.patch( - `/api/v2/organizations/${organization}`, - params, - ); - return response.data; - }; - - /** - * @param organization Can be the organization's ID or name - */ - deleteOrganization = async (organization: string) => { - await this.axios.delete( - `/api/v2/organizations/${organization}`, - ); - }; - - /** - * @param organization Can be the organization's ID or name - */ - getOrganization = async ( - organization: string, - ): Promise => { - const response = await this.axios.get( - `/api/v2/organizations/${organization}`, - ); - - return response.data; - }; - - /** - * @param organization Can be the organization's ID or name - */ - getOrganizationMembers = async (organization: string) => { - const response = await this.axios.get< - TypesGen.OrganizationMemberWithUserData[] - >(`/api/v2/organizations/${organization}/members`); - - return response.data; - }; - - /** - * @param organization Can be the organization's ID or name - */ - getOrganizationRoles = async (organization: string) => { - const response = await this.axios.get( - `/api/v2/organizations/${organization}/members/roles`, - ); - - return response.data; - }; - - /** - * @param organization Can be the organization's ID or name - */ - updateOrganizationMemberRoles = async ( - organization: string, - userId: string, - roles: TypesGen.SlimRole["name"][], - ): Promise => { - const response = await this.axios.put( - `/api/v2/organizations/${organization}/members/${userId}/roles`, - { roles }, - ); - - return response.data; - }; - - /** - * @param organization Can be the organization's ID or name - */ - createOrganizationRole = async ( - organization: string, - role: TypesGen.Role, - ): Promise => { - const response = await this.axios.post( - `/api/v2/organizations/${organization}/members/roles`, - role, - ); - - return response.data; - }; - - /** - * @param organization Can be the organization's ID or name - */ - updateOrganizationRole = async ( - organization: string, - role: TypesGen.Role, - ): Promise => { - const response = await this.axios.put( - `/api/v2/organizations/${organization}/members/roles`, - role, - ); - - return response.data; - }; - - /** - * @param organization Can be the organization's ID or name - */ - deleteOrganizationRole = async (organization: string, roleName: string) => { - await this.axios.delete( - `/api/v2/organizations/${organization}/members/roles/${roleName}`, - ); - }; - - /** - * @param organization Can be the organization's ID or name - */ - addOrganizationMember = async (organization: string, userId: string) => { - const response = await this.axios.post( - `/api/v2/organizations/${organization}/members/${userId}`, - ); - - return response.data; - }; - - /** - * @param organization Can be the organization's ID or name - */ - removeOrganizationMember = async (organization: string, userId: string) => { - await this.axios.delete( - `/api/v2/organizations/${organization}/members/${userId}`, - ); - }; - - getOrganizations = async (): Promise => { - const response = await this.axios.get( - "/api/v2/organizations", - ); - return response.data; - }; - - getMyOrganizations = async (): Promise => { - const response = await this.axios.get( - "/api/v2/users/me/organizations", - ); - return response.data; - }; - - /** - * @param organization Can be the organization's ID or name - */ - getProvisionerDaemonsByOrganization = async ( - organization: string, - ): Promise => { - const response = await this.axios.get( - `/api/v2/organizations/${organization}/provisionerdaemons`, - ); - return response.data; - }; - - getTemplate = async (templateId: string): Promise => { - const response = await this.axios.get( - `/api/v2/templates/${templateId}`, - ); - - return response.data; - }; - - getTemplates = async ( - options?: GetTemplatesOptions | GetTemplatesQuery, - ): Promise => { - const params = normalizeGetTemplatesOptions(options); - const response = await this.axios.get( - "/api/v2/templates", - { params }, - ); - - return response.data; - }; - - /** - * @param organization Can be the organization's ID or name - */ - getTemplatesByOrganization = async ( - organization: string, - options?: GetTemplatesOptions, - ): Promise => { - const params = normalizeGetTemplatesOptions(options); - const response = await this.axios.get( - `/api/v2/organizations/${organization}/templates`, - { params }, - ); - - return response.data; - }; - - /** - * @param organization Can be the organization's ID or name - */ - getTemplateByName = async ( - organization: string, - name: string, - ): Promise => { - const response = await this.axios.get( - `/api/v2/organizations/${organization}/templates/${name}`, - ); - - return response.data; - }; - - getTemplateVersion = async ( - versionId: string, - ): Promise => { - const response = await this.axios.get( - `/api/v2/templateversions/${versionId}`, - ); - - return response.data; - }; - - getTemplateVersionResources = async ( - versionId: string, - ): Promise => { - const response = await this.axios.get( - `/api/v2/templateversions/${versionId}/resources`, - ); - - return response.data; - }; - - getTemplateVersionVariables = async ( - versionId: string, - ): Promise => { - // Defined as separate variable to avoid wonky Prettier formatting because - // the type definition is so long - type VerArray = TypesGen.TemplateVersionVariable[]; - - const response = await this.axios.get( - `/api/v2/templateversions/${versionId}/variables`, - ); - - return response.data; - }; - - getTemplateVersions = async ( - templateId: string, - ): Promise => { - const response = await this.axios.get( - `/api/v2/templates/${templateId}/versions`, - ); - return response.data; - }; - - /** - * @param organization Can be the organization's ID or name - */ - getTemplateVersionByName = async ( - organization: string, - templateName: string, - versionName: string, - ): Promise => { - const response = await this.axios.get( - `/api/v2/organizations/${organization}/templates/${templateName}/versions/${versionName}`, - ); - - return response.data; - }; - - /** - * @param organization Can be the organization's ID or name - */ - getPreviousTemplateVersionByName = async ( - organization: string, - templateName: string, - versionName: string, - ) => { - try { - const response = await this.axios.get( - `/api/v2/organizations/${organization}/templates/${templateName}/versions/${versionName}/previous`, - ); - - return response.data; - } catch (error) { - // When there is no previous version, like the first version of a - // template, the API returns 404 so in this case we can safely return - // undefined - const is404 = - isAxiosError(error) && error.response && error.response.status === 404; - - if (is404) { - return undefined; - } - - throw error; - } - }; - - /** - * @param organization Can be the organization's ID or name - */ - createTemplateVersion = async ( - organization: string, - data: TypesGen.CreateTemplateVersionRequest, - ): Promise => { - const response = await this.axios.post( - `/api/v2/organizations/${organization}/templateversions`, - data, - ); - - return response.data; - }; - - getTemplateVersionExternalAuth = async ( - versionId: string, - ): Promise => { - const response = await this.axios.get( - `/api/v2/templateversions/${versionId}/external-auth`, - ); - - return response.data; - }; - - getTemplateVersionRichParameters = async ( - versionId: string, - ): Promise => { - const response = await this.axios.get( - `/api/v2/templateversions/${versionId}/rich-parameters`, - ); - return response.data; - }; - - /** - * @param organization Can be the organization's ID or name - */ - createTemplate = async ( - organization: string, - data: TypesGen.CreateTemplateRequest, - ): Promise => { - const response = await this.axios.post( - `/api/v2/organizations/${organization}/templates`, - data, - ); - - return response.data; - }; - - updateActiveTemplateVersion = async ( - templateId: string, - data: TypesGen.UpdateActiveTemplateVersion, - ) => { - const response = await this.axios.patch( - `/api/v2/templates/${templateId}/versions`, - data, - ); - return response.data; - }; - - patchTemplateVersion = async ( - templateVersionId: string, - data: TypesGen.PatchTemplateVersionRequest, - ) => { - const response = await this.axios.patch( - `/api/v2/templateversions/${templateVersionId}`, - data, - ); - - return response.data; - }; - - archiveTemplateVersion = async (templateVersionId: string) => { - const response = await this.axios.post( - `/api/v2/templateversions/${templateVersionId}/archive`, - ); - - return response.data; - }; - - unarchiveTemplateVersion = async (templateVersionId: string) => { - const response = await this.axios.post( - `/api/v2/templateversions/${templateVersionId}/unarchive`, - ); - return response.data; - }; - - updateTemplateMeta = async ( - templateId: string, - data: TypesGen.UpdateTemplateMeta, - ): Promise => { - const response = await this.axios.patch( - `/api/v2/templates/${templateId}`, - data, - ); - - // On 304 response there is no data payload. - if (response.status === 304) { - return null; - } - - return response.data; - }; - - deleteTemplate = async (templateId: string): Promise => { - const response = await this.axios.delete( - `/api/v2/templates/${templateId}`, - ); - - return response.data; - }; - - getWorkspace = async ( - workspaceId: string, - params?: TypesGen.WorkspaceOptions, - ): Promise => { - const response = await this.axios.get( - `/api/v2/workspaces/${workspaceId}`, - { params }, - ); - - return response.data; - }; - - getWorkspaces = async ( - options: TypesGen.WorkspacesRequest, - ): Promise => { - const url = getURLWithSearchParams("/api/v2/workspaces", options); - const response = await this.axios.get(url); - return response.data; - }; - - getWorkspaceByOwnerAndName = async ( - username = "me", - workspaceName: string, - params?: TypesGen.WorkspaceOptions, - ): Promise => { - const response = await this.axios.get( - `/api/v2/users/${username}/workspace/${workspaceName}`, - { params }, - ); - - return response.data; - }; - - getWorkspaceBuildByNumber = async ( - username = "me", - workspaceName: string, - buildNumber: number, - ): Promise => { - const response = await this.axios.get( - `/api/v2/users/${username}/workspace/${workspaceName}/builds/${buildNumber}`, - ); - - return response.data; - }; - - waitForBuild = (build: TypesGen.WorkspaceBuild) => { - return new Promise((res, reject) => { - void (async () => { - let latestJobInfo: TypesGen.ProvisionerJob | undefined = undefined; - - while ( - !["succeeded", "canceled"].some((status) => - latestJobInfo?.status.includes(status), - ) - ) { - const { job } = await this.getWorkspaceBuildByNumber( - build.workspace_owner_name, - build.workspace_name, - build.build_number, - ); - - latestJobInfo = job; - if (latestJobInfo.status === "failed") { - return reject(latestJobInfo); - } - - await delay(1000); - } - - return res(latestJobInfo); - })(); - }); - }; - - postWorkspaceBuild = async ( - workspaceId: string, - data: TypesGen.CreateWorkspaceBuildRequest, - ): Promise => { - const response = await this.axios.post( - `/api/v2/workspaces/${workspaceId}/builds`, - data, - ); - - return response.data; - }; - - startWorkspace = ( - workspaceId: string, - templateVersionId: string, - logLevel?: TypesGen.ProvisionerLogLevel, - buildParameters?: TypesGen.WorkspaceBuildParameter[], - ) => { - return this.postWorkspaceBuild(workspaceId, { - transition: "start", - template_version_id: templateVersionId, - log_level: logLevel, - rich_parameter_values: buildParameters, - }); - }; - - stopWorkspace = ( - workspaceId: string, - logLevel?: TypesGen.ProvisionerLogLevel, - ) => { - return this.postWorkspaceBuild(workspaceId, { - transition: "stop", - log_level: logLevel, - }); - }; - - deleteWorkspace = (workspaceId: string, options?: DeleteWorkspaceOptions) => { - return this.postWorkspaceBuild(workspaceId, { - transition: "delete", - ...options, - }); - }; - - cancelWorkspaceBuild = async ( - workspaceBuildId: TypesGen.WorkspaceBuild["id"], - ): Promise => { - const response = await this.axios.patch( - `/api/v2/workspacebuilds/${workspaceBuildId}/cancel`, - ); - - return response.data; - }; - - updateWorkspaceDormancy = async ( - workspaceId: string, - dormant: boolean, - ): Promise => { - const data: TypesGen.UpdateWorkspaceDormancy = { dormant }; - const response = await this.axios.put( - `/api/v2/workspaces/${workspaceId}/dormant`, - data, - ); - - return response.data; - }; - - updateWorkspaceAutomaticUpdates = async ( - workspaceId: string, - automaticUpdates: TypesGen.AutomaticUpdates, - ): Promise => { - const req: TypesGen.UpdateWorkspaceAutomaticUpdatesRequest = { - automatic_updates: automaticUpdates, - }; - - const response = await this.axios.put( - `/api/v2/workspaces/${workspaceId}/autoupdates`, - req, - ); - - return response.data; - }; - - restartWorkspace = async ({ - workspace, - buildParameters, - }: RestartWorkspaceParameters): Promise => { - const stopBuild = await this.stopWorkspace(workspace.id); - const awaitedStopBuild = await this.waitForBuild(stopBuild); - - // If the restart is canceled halfway through, make sure we bail - if (awaitedStopBuild?.status === "canceled") { - return; - } - - const startBuild = await this.startWorkspace( - workspace.id, - workspace.latest_build.template_version_id, - undefined, - buildParameters, - ); - - await this.waitForBuild(startBuild); - }; - - cancelTemplateVersionBuild = async ( - templateVersionId: TypesGen.TemplateVersion["id"], - ): Promise => { - const response = await this.axios.patch( - `/api/v2/templateversions/${templateVersionId}/cancel`, - ); - - return response.data; - }; - - createUser = async ( - user: TypesGen.CreateUserRequest, - ): Promise => { - const response = await this.axios.post( - "/api/v2/users", - user, - ); - - return response.data; - }; - - createWorkspace = async ( - userId = "me", - workspace: TypesGen.CreateWorkspaceRequest, - ): Promise => { - const response = await this.axios.post( - `/api/v2/users/${userId}/workspaces`, - workspace, - ); - - return response.data; - }; - - patchWorkspace = async ( - workspaceId: string, - data: TypesGen.UpdateWorkspaceRequest, - ): Promise => { - await this.axios.patch(`/api/v2/workspaces/${workspaceId}`, data); - }; - - getBuildInfo = async (): Promise => { - const response = await this.axios.get("/api/v2/buildinfo"); - return response.data; - }; - - getUpdateCheck = async (): Promise => { - const response = await this.axios.get("/api/v2/updatecheck"); - return response.data; - }; - - putWorkspaceAutostart = async ( - workspaceID: string, - autostart: TypesGen.UpdateWorkspaceAutostartRequest, - ): Promise => { - const payload = JSON.stringify(autostart); - await this.axios.put( - `/api/v2/workspaces/${workspaceID}/autostart`, - payload, - { headers: { ...BASE_CONTENT_TYPE_JSON } }, - ); - }; - - putWorkspaceAutostop = async ( - workspaceID: string, - ttl: TypesGen.UpdateWorkspaceTTLRequest, - ): Promise => { - const payload = JSON.stringify(ttl); - await this.axios.put(`/api/v2/workspaces/${workspaceID}/ttl`, payload, { - headers: { ...BASE_CONTENT_TYPE_JSON }, - }); - }; - - updateProfile = async ( - userId: string, - data: TypesGen.UpdateUserProfileRequest, - ): Promise => { - const response = await this.axios.put( - `/api/v2/users/${userId}/profile`, - data, - ); - return response.data; - }; - - updateAppearanceSettings = async ( - userId: string, - data: TypesGen.UpdateUserAppearanceSettingsRequest, - ): Promise => { - const response = await this.axios.put( - `/api/v2/users/${userId}/appearance`, - data, - ); - return response.data; - }; - - getUserQuietHoursSchedule = async ( - userId: TypesGen.User["id"], - ): Promise => { - const response = await this.axios.get( - `/api/v2/users/${userId}/quiet-hours`, - ); - return response.data; - }; - - updateUserQuietHoursSchedule = async ( - userId: TypesGen.User["id"], - data: TypesGen.UpdateUserQuietHoursScheduleRequest, - ): Promise => { - const response = await this.axios.put( - `/api/v2/users/${userId}/quiet-hours`, - data, - ); - - return response.data; - }; - - activateUser = async ( - userId: TypesGen.User["id"], - ): Promise => { - const response = await this.axios.put( - `/api/v2/users/${userId}/status/activate`, - ); - return response.data; - }; - - suspendUser = async (userId: TypesGen.User["id"]): Promise => { - const response = await this.axios.put( - `/api/v2/users/${userId}/status/suspend`, - ); - - return response.data; - }; - - deleteUser = async (userId: TypesGen.User["id"]): Promise => { - await this.axios.delete(`/api/v2/users/${userId}`); - }; - - // API definition: - // https://github.com/coder/coder/blob/db665e7261f3c24a272ccec48233a3e276878239/coderd/users.go#L33-L53 - hasFirstUser = async (): Promise => { - try { - // If it is success, it is true - await this.axios.get("/api/v2/users/first"); - return true; - } catch (error) { - // If it returns a 404, it is false - if (isAxiosError(error) && error.response?.status === 404) { - return false; - } - - throw error; - } - }; - - createFirstUser = async ( - req: TypesGen.CreateFirstUserRequest, - ): Promise => { - const response = await this.axios.post("/api/v2/users/first", req); - return response.data; - }; - - updateUserPassword = async ( - userId: TypesGen.User["id"], - updatePassword: TypesGen.UpdateUserPasswordRequest, - ): Promise => { - await this.axios.put(`/api/v2/users/${userId}/password`, updatePassword); - }; - - getRoles = async (): Promise> => { - const response = await this.axios.get( - "/api/v2/users/roles", - ); - - return response.data; - }; - - updateUserRoles = async ( - roles: TypesGen.SlimRole["name"][], - userId: TypesGen.User["id"], - ): Promise => { - const response = await this.axios.put( - `/api/v2/users/${userId}/roles`, - { roles }, - ); - - return response.data; - }; - - getUserSSHKey = async (userId = "me"): Promise => { - const response = await this.axios.get( - `/api/v2/users/${userId}/gitsshkey`, - ); - - return response.data; - }; - - regenerateUserSSHKey = async (userId = "me"): Promise => { - const response = await this.axios.put( - `/api/v2/users/${userId}/gitsshkey`, - ); - - return response.data; - }; - - getWorkspaceBuilds = async ( - workspaceId: string, - req?: TypesGen.WorkspaceBuildsRequest, - ) => { - const response = await this.axios.get( - getURLWithSearchParams(`/api/v2/workspaces/${workspaceId}/builds`, req), - ); - - return response.data; - }; - - getWorkspaceBuildLogs = async ( - buildId: string, - ): Promise => { - const response = await this.axios.get( - `/api/v2/workspacebuilds/${buildId}/logs`, - ); - - return response.data; - }; - - getWorkspaceAgentLogs = async ( - agentID: string, - ): Promise => { - const response = await this.axios.get( - `/api/v2/workspaceagents/${agentID}/logs`, - ); - - return response.data; - }; - - putWorkspaceExtension = async ( - workspaceId: string, - newDeadline: dayjs.Dayjs, - ): Promise => { - await this.axios.put(`/api/v2/workspaces/${workspaceId}/extend`, { - deadline: newDeadline, - }); - }; - - refreshEntitlements = async (): Promise => { - await this.axios.post("/api/v2/licenses/refresh-entitlements"); - }; - - getEntitlements = async (): Promise => { - try { - const response = await this.axios.get( - "/api/v2/entitlements", - ); - - return response.data; - } catch (ex) { - if (isAxiosError(ex) && ex.response?.status === 404) { - return { - errors: [], - features: withDefaultFeatures({}), - has_license: false, - require_telemetry: false, - trial: false, - warnings: [], - refreshed_at: "", - }; - } - throw ex; - } - }; - - getExperiments = async (): Promise => { - try { - const response = await this.axios.get( - "/api/v2/experiments", - ); - - return response.data; - } catch (error) { - if (isAxiosError(error) && error.response?.status === 404) { - return []; - } - - throw error; - } - }; - - getAvailableExperiments = - async (): Promise => { - try { - const response = await this.axios.get("/api/v2/experiments/available"); - - return response.data; - } catch (error) { - if (isAxiosError(error) && error.response?.status === 404) { - return { safe: [] }; - } - throw error; - } - }; - - getExternalAuthProvider = async ( - provider: string, - ): Promise => { - const res = await this.axios.get(`/api/v2/external-auth/${provider}`); - return res.data; - }; - - getExternalAuthDevice = async ( - provider: string, - ): Promise => { - const resp = await this.axios.get( - `/api/v2/external-auth/${provider}/device`, - ); - return resp.data; - }; - - exchangeExternalAuthDevice = async ( - provider: string, - req: TypesGen.ExternalAuthDeviceExchange, - ): Promise => { - const resp = await this.axios.post( - `/api/v2/external-auth/${provider}/device`, - req, - ); - - return resp.data; - }; - - getUserExternalAuthProviders = - async (): Promise => { - const resp = await this.axios.get("/api/v2/external-auth"); - return resp.data; - }; - - unlinkExternalAuthProvider = async (provider: string): Promise => { - const resp = await this.axios.delete(`/api/v2/external-auth/${provider}`); - return resp.data; - }; - - getOAuth2ProviderApps = async ( - filter?: TypesGen.OAuth2ProviderAppFilter, - ): Promise => { - const params = filter?.user_id - ? new URLSearchParams({ user_id: filter.user_id }).toString() - : ""; - - const resp = await this.axios.get(`/api/v2/oauth2-provider/apps?${params}`); - return resp.data; - }; - - getOAuth2ProviderApp = async ( - id: string, - ): Promise => { - const resp = await this.axios.get(`/api/v2/oauth2-provider/apps/${id}`); - return resp.data; - }; - - postOAuth2ProviderApp = async ( - data: TypesGen.PostOAuth2ProviderAppRequest, - ): Promise => { - const response = await this.axios.post( - "/api/v2/oauth2-provider/apps", - data, - ); - return response.data; - }; - - putOAuth2ProviderApp = async ( - id: string, - data: TypesGen.PutOAuth2ProviderAppRequest, - ): Promise => { - const response = await this.axios.put( - `/api/v2/oauth2-provider/apps/${id}`, - data, - ); - return response.data; - }; - - deleteOAuth2ProviderApp = async (id: string): Promise => { - await this.axios.delete(`/api/v2/oauth2-provider/apps/${id}`); - }; - - getOAuth2ProviderAppSecrets = async ( - id: string, - ): Promise => { - const resp = await this.axios.get( - `/api/v2/oauth2-provider/apps/${id}/secrets`, - ); - return resp.data; - }; - - postOAuth2ProviderAppSecret = async ( - id: string, - ): Promise => { - const resp = await this.axios.post( - `/api/v2/oauth2-provider/apps/${id}/secrets`, - ); - return resp.data; - }; - - deleteOAuth2ProviderAppSecret = async ( - appId: string, - secretId: string, - ): Promise => { - await this.axios.delete( - `/api/v2/oauth2-provider/apps/${appId}/secrets/${secretId}`, - ); - }; - - revokeOAuth2ProviderApp = async (appId: string): Promise => { - await this.axios.delete(`/oauth2/tokens?client_id=${appId}`); - }; - - getAuditLogs = async ( - options: TypesGen.AuditLogsRequest, - ): Promise => { - const url = getURLWithSearchParams("/api/v2/audit", options); - const response = await this.axios.get(url); - return response.data; - }; - - getTemplateDAUs = async ( - templateId: string, - ): Promise => { - const response = await this.axios.get( - `/api/v2/templates/${templateId}/daus`, - ); - - return response.data; - }; - - getDeploymentDAUs = async ( - // Default to user's local timezone. - // As /api/v2/insights/daus only accepts whole-number values for tz_offset - // we truncate the tz offset down to the closest hour. - offset = Math.trunc(new Date().getTimezoneOffset() / 60), - ): Promise => { - const response = await this.axios.get( - `/api/v2/insights/daus?tz_offset=${offset}`, - ); - - return response.data; - }; - - getTemplateACLAvailable = async ( - templateId: string, - options: TypesGen.UsersRequest, - ): Promise => { - const url = getURLWithSearchParams( - `/api/v2/templates/${templateId}/acl/available`, - options, - ).toString(); - - const response = await this.axios.get(url); - return response.data; - }; - - getTemplateACL = async ( - templateId: string, - ): Promise => { - const response = await this.axios.get( - `/api/v2/templates/${templateId}/acl`, - ); - - return response.data; - }; - - updateTemplateACL = async ( - templateId: string, - data: TypesGen.UpdateTemplateACL, - ): Promise<{ message: string }> => { - const response = await this.axios.patch( - `/api/v2/templates/${templateId}/acl`, - data, - ); - - return response.data; - }; - - getApplicationsHost = async (): Promise => { - const response = await this.axios.get("/api/v2/applications/host"); - return response.data; - }; - - /** - * @param organization Can be the organization's ID or name - */ - getGroups = async (organization: string): Promise => { - const response = await this.axios.get( - `/api/v2/organizations/${organization}/groups`, - ); - - return response.data; - }; - - /** - * @param organization Can be the organization's ID or name - */ - createGroup = async ( - organization: string, - data: TypesGen.CreateGroupRequest, - ): Promise => { - const response = await this.axios.post( - `/api/v2/organizations/${organization}/groups`, - data, - ); - return response.data; - }; - - /** - * @param organization Can be the organization's ID or name - */ - getGroup = async ( - organization: string, - groupName: string, - ): Promise => { - const response = await this.axios.get( - `/api/v2/organizations/${organization}/groups/${groupName}`, - ); - return response.data; - }; - - patchGroup = async ( - groupId: string, - data: TypesGen.PatchGroupRequest, - ): Promise => { - const response = await this.axios.patch(`/api/v2/groups/${groupId}`, data); - return response.data; - }; - - addMember = async (groupId: string, userId: string) => { - return this.patchGroup(groupId, { - name: "", - add_users: [userId], - remove_users: [], - }); - }; - - removeMember = async (groupId: string, userId: string) => { - return this.patchGroup(groupId, { - name: "", - display_name: "", - add_users: [], - remove_users: [userId], - }); - }; - - deleteGroup = async (groupId: string): Promise => { - await this.axios.delete(`/api/v2/groups/${groupId}`); - }; - - getWorkspaceQuota = async ( - username: string, - ): Promise => { - const response = await this.axios.get( - `/api/v2/workspace-quota/${encodeURIComponent(username)}`, - ); - return response.data; - }; - - getAgentListeningPorts = async ( - agentID: string, - ): Promise => { - const response = await this.axios.get( - `/api/v2/workspaceagents/${agentID}/listening-ports`, - ); - return response.data; - }; - - getWorkspaceAgentSharedPorts = async ( - workspaceID: string, - ): Promise => { - const response = await this.axios.get( - `/api/v2/workspaces/${workspaceID}/port-share`, - ); - return response.data; - }; - - upsertWorkspaceAgentSharedPort = async ( - workspaceID: string, - req: TypesGen.UpsertWorkspaceAgentPortShareRequest, - ): Promise => { - const response = await this.axios.post( - `/api/v2/workspaces/${workspaceID}/port-share`, - req, - ); - return response.data; - }; - - deleteWorkspaceAgentSharedPort = async ( - workspaceID: string, - req: TypesGen.DeleteWorkspaceAgentPortShareRequest, - ): Promise => { - const response = await this.axios.delete( - `/api/v2/workspaces/${workspaceID}/port-share`, - { data: req }, - ); - - return response.data; - }; - - // getDeploymentSSHConfig is used by the VSCode-Extension. - getDeploymentSSHConfig = async (): Promise => { - const response = await this.axios.get("/api/v2/deployment/ssh"); - return response.data; - }; - - getDeploymentConfig = async (): Promise => { - const response = await this.axios.get("/api/v2/deployment/config"); - return response.data; - }; - - getDeploymentStats = async (): Promise => { - const response = await this.axios.get("/api/v2/deployment/stats"); - return response.data; - }; - - getReplicas = async (): Promise => { - const response = await this.axios.get("/api/v2/replicas"); - return response.data; - }; - - getFile = async (fileId: string): Promise => { - const response = await this.axios.get( - `/api/v2/files/${fileId}`, - { responseType: "arraybuffer" }, - ); - - return response.data; - }; - - getWorkspaceProxyRegions = async (): Promise< - TypesGen.RegionsResponse - > => { - const response = - await this.axios.get>( - "/api/v2/regions", - ); - - return response.data; - }; - - getWorkspaceProxies = async (): Promise< - TypesGen.RegionsResponse - > => { - const response = await this.axios.get< - TypesGen.RegionsResponse - >("/api/v2/workspaceproxies"); - - return response.data; - }; - - createWorkspaceProxy = async ( - b: TypesGen.CreateWorkspaceProxyRequest, - ): Promise => { - const response = await this.axios.post("/api/v2/workspaceproxies", b); - return response.data; - }; - - getAppearance = async (): Promise => { - try { - const response = await this.axios.get("/api/v2/appearance"); - return response.data || {}; - } catch (ex) { - if (isAxiosError(ex) && ex.response?.status === 404) { - return { - application_name: "", - logo_url: "", - announcement_banners: [], - service_banner: { - enabled: false, - }, - }; - } - - throw ex; - } - }; - - updateAppearance = async ( - b: TypesGen.AppearanceConfig, - ): Promise => { - const response = await this.axios.put("/api/v2/appearance", b); - return response.data; - }; - - /** - * @param organization Can be the organization's ID or name - */ - getTemplateExamples = async (): Promise => { - const response = await this.axios.get("/api/v2/templates/examples"); - - return response.data; - }; - - uploadFile = async (file: File): Promise => { - const response = await this.axios.post("/api/v2/files", file, { - headers: { "Content-Type": "application/x-tar" }, - }); - - return response.data; - }; - - getTemplateVersionLogs = async ( - versionId: string, - ): Promise => { - const response = await this.axios.get( - `/api/v2/templateversions/${versionId}/logs`, - ); - return response.data; - }; - - updateWorkspaceVersion = async ( - workspace: TypesGen.Workspace, - ): Promise => { - const template = await this.getTemplate(workspace.template_id); - return this.startWorkspace(workspace.id, template.active_version_id); - }; - - getWorkspaceBuildParameters = async ( - workspaceBuildId: TypesGen.WorkspaceBuild["id"], - ): Promise => { - const response = await this.axios.get( - `/api/v2/workspacebuilds/${workspaceBuildId}/parameters`, - ); - - return response.data; - }; - - getLicenses = async (): Promise => { - const response = await this.axios.get("/api/v2/licenses"); - return response.data; - }; - - createLicense = async ( - data: TypesGen.AddLicenseRequest, - ): Promise => { - const response = await this.axios.post("/api/v2/licenses", data); - return response.data; - }; - - removeLicense = async (licenseId: number): Promise => { - await this.axios.delete(`/api/v2/licenses/${licenseId}`); - }; - - /** Steps to change the workspace version - * - Get the latest template to access the latest active version - * - Get the current build parameters - * - Get the template parameters - * - Update the build parameters and check if there are missed parameters for - * the new version - * - If there are missing parameters raise an error - * - Create a build with the version and updated build parameters - */ - changeWorkspaceVersion = async ( - workspace: TypesGen.Workspace, - templateVersionId: string, - newBuildParameters: TypesGen.WorkspaceBuildParameter[] = [], - ): Promise => { - const [currentBuildParameters, templateParameters] = await Promise.all([ - this.getWorkspaceBuildParameters(workspace.latest_build.id), - this.getTemplateVersionRichParameters(templateVersionId), - ]); - - const missingParameters = getMissingParameters( - currentBuildParameters, - newBuildParameters, - templateParameters, - ); - - if (missingParameters.length > 0) { - throw new MissingBuildParameters(missingParameters, templateVersionId); - } - - return this.postWorkspaceBuild(workspace.id, { - transition: "start", - template_version_id: templateVersionId, - rich_parameter_values: newBuildParameters, - }); - }; - - /** Steps to update the workspace - * - Get the latest template to access the latest active version - * - Get the current build parameters - * - Get the template parameters - * - Update the build parameters and check if there are missed parameters for - * the newest version - * - If there are missing parameters raise an error - * - Create a build with the latest version and updated build parameters - */ - updateWorkspace = async ( - workspace: TypesGen.Workspace, - newBuildParameters: TypesGen.WorkspaceBuildParameter[] = [], - ): Promise => { - const [template, oldBuildParameters] = await Promise.all([ - this.getTemplate(workspace.template_id), - this.getWorkspaceBuildParameters(workspace.latest_build.id), - ]); - - const activeVersionId = template.active_version_id; - const templateParameters = - await this.getTemplateVersionRichParameters(activeVersionId); - - const missingParameters = getMissingParameters( - oldBuildParameters, - newBuildParameters, - templateParameters, - ); - - if (missingParameters.length > 0) { - throw new MissingBuildParameters(missingParameters, activeVersionId); - } - - return this.postWorkspaceBuild(workspace.id, { - transition: "start", - template_version_id: activeVersionId, - rich_parameter_values: newBuildParameters, - }); - }; - - getWorkspaceResolveAutostart = async ( - workspaceId: string, - ): Promise => { - const response = await this.axios.get( - `/api/v2/workspaces/${workspaceId}/resolve-autostart`, - ); - return response.data; - }; - - issueReconnectingPTYSignedToken = async ( - params: TypesGen.IssueReconnectingPTYSignedTokenRequest, - ): Promise => { - const response = await this.axios.post( - "/api/v2/applications/reconnecting-pty-signed-token", - params, - ); - - return response.data; - }; - - getWorkspaceParameters = async (workspace: TypesGen.Workspace) => { - const latestBuild = workspace.latest_build; - const [templateVersionRichParameters, buildParameters] = await Promise.all([ - this.getTemplateVersionRichParameters(latestBuild.template_version_id), - this.getWorkspaceBuildParameters(latestBuild.id), - ]); - - return { - templateVersionRichParameters, - buildParameters, - }; - }; - - getInsightsUserLatency = async ( - filters: InsightsParams, - ): Promise => { - const params = new URLSearchParams(filters); - const response = await this.axios.get( - `/api/v2/insights/user-latency?${params}`, - ); - - return response.data; - }; - - getInsightsUserActivity = async ( - filters: InsightsParams, - ): Promise => { - const params = new URLSearchParams(filters); - const response = await this.axios.get( - `/api/v2/insights/user-activity?${params}`, - ); - - return response.data; - }; - - getInsightsTemplate = async ( - params: InsightsTemplateParams, - ): Promise => { - const searchParams = new URLSearchParams(params); - const response = await this.axios.get( - `/api/v2/insights/templates?${searchParams}`, - ); - - return response.data; - }; - - getHealth = async (force = false) => { - const params = new URLSearchParams({ force: force.toString() }); - const response = await this.axios.get( - `/api/v2/debug/health?${params}`, - ); - return response.data; - }; - - getHealthSettings = async (): Promise => { - const res = await this.axios.get( - "/api/v2/debug/health/settings", - ); - - return res.data; - }; - - updateHealthSettings = async (data: TypesGen.UpdateHealthSettings) => { - const response = await this.axios.put( - "/api/v2/debug/health/settings", - data, - ); - - return response.data; - }; - - putFavoriteWorkspace = async (workspaceID: string) => { - await this.axios.put(`/api/v2/workspaces/${workspaceID}/favorite`); - }; - - deleteFavoriteWorkspace = async (workspaceID: string) => { - await this.axios.delete(`/api/v2/workspaces/${workspaceID}/favorite`); - }; - - getJFrogXRayScan = async (options: GetJFrogXRayScanParams) => { - const searchParams = new URLSearchParams({ - workspace_id: options.workspaceId, - agent_id: options.agentId, - }); - - try { - const res = await this.axios.get( - `/api/v2/integrations/jfrog/xray-scan?${searchParams}`, - ); - - return res.data; - } catch (error) { - if (isAxiosError(error) && error.response?.status === 404) { - // react-query library does not allow undefined to be returned as a - // query result - return null; - } - - throw error; - } - }; - - postWorkspaceUsage = async ( - workspaceID: string, - options: PostWorkspaceUsageRequest, - ) => { - const response = await this.axios.post( - `/api/v2/workspaces/${workspaceID}/usage`, - options, - ); - - return response.data; - }; - - getUserNotificationPreferences = async (userId: string) => { - const res = await this.axios.get( - `/api/v2/users/${userId}/notifications/preferences`, - ); - return res.data ?? []; - }; - - putUserNotificationPreferences = async ( - userId: string, - req: TypesGen.UpdateUserNotificationPreferences, - ) => { - const res = await this.axios.put( - `/api/v2/users/${userId}/notifications/preferences`, - req, - ); - return res.data; - }; - - getSystemNotificationTemplates = async () => { - const res = await this.axios.get( - "/api/v2/notifications/templates/system", - ); - return res.data; - }; - - getNotificationDispatchMethods = async () => { - const res = await this.axios.get( - "/api/v2/notifications/dispatch-methods", - ); - return res.data; - }; - - updateNotificationTemplateMethod = async ( - templateId: string, - req: TypesGen.UpdateNotificationTemplateMethod, - ) => { - const res = await this.axios.put( - `/api/v2/notifications/templates/${templateId}/method`, - req, - ); - return res.data; - }; + constructor(protected readonly axios: AxiosInstance) {} + + login = async ( + email: string, + password: string, + ): Promise => { + const payload = JSON.stringify({ email, password }); + const response = await this.axios.post( + "/api/v2/users/login", + payload, + { headers: { ...BASE_CONTENT_TYPE_JSON } }, + ); + + return response.data; + }; + + convertToOAUTH = async (request: TypesGen.ConvertLoginRequest) => { + const response = await this.axios.post( + "/api/v2/users/me/convert-login", + request, + ); + + return response.data; + }; + + logout = async (): Promise => { + return this.axios.post("/api/v2/users/logout"); + }; + + getAuthenticatedUser = async () => { + const response = await this.axios.get("/api/v2/users/me"); + return response.data; + }; + + getUserParameters = async (templateID: string) => { + const response = await this.axios.get( + `/api/v2/users/me/autofill-parameters?template_id=${templateID}`, + ); + + return response.data; + }; + + getAuthMethods = async (): Promise => { + const response = await this.axios.get( + "/api/v2/users/authmethods", + ); + + return response.data; + }; + + getUserLoginType = async (): Promise => { + const response = await this.axios.get( + "/api/v2/users/me/login-type", + ); + + return response.data; + }; + + checkAuthorization = async ( + params: TypesGen.AuthorizationRequest, + ): Promise => { + const response = await this.axios.post( + "/api/v2/authcheck", + params, + ); + + return response.data; + }; + + getApiKey = async (): Promise => { + const response = await this.axios.post( + "/api/v2/users/me/keys", + ); + + return response.data; + }; + + getTokens = async ( + params: TypesGen.TokensFilter, + ): Promise => { + const response = await this.axios.get( + "/api/v2/users/me/keys/tokens", + { params }, + ); + + return response.data; + }; + + deleteToken = async (keyId: string): Promise => { + await this.axios.delete(`/api/v2/users/me/keys/${keyId}`); + }; + + createToken = async ( + params: TypesGen.CreateTokenRequest, + ): Promise => { + const response = await this.axios.post( + "/api/v2/users/me/keys/tokens", + params, + ); + + return response.data; + }; + + getTokenConfig = async (): Promise => { + const response = await this.axios.get( + "/api/v2/users/me/keys/tokens/tokenconfig", + ); + + return response.data; + }; + + getUsers = async ( + options: TypesGen.UsersRequest, + signal?: AbortSignal, + ): Promise => { + const url = getURLWithSearchParams("/api/v2/users", options); + const response = await this.axios.get( + url.toString(), + { signal }, + ); + + return response.data; + }; + + createOrganization = async (params: TypesGen.CreateOrganizationRequest) => { + const response = await this.axios.post( + "/api/v2/organizations", + params, + ); + return response.data; + }; + + /** + * @param organization Can be the organization's ID or name + */ + updateOrganization = async ( + organization: string, + params: TypesGen.UpdateOrganizationRequest, + ) => { + const response = await this.axios.patch( + `/api/v2/organizations/${organization}`, + params, + ); + return response.data; + }; + + /** + * @param organization Can be the organization's ID or name + */ + deleteOrganization = async (organization: string) => { + await this.axios.delete( + `/api/v2/organizations/${organization}`, + ); + }; + + /** + * @param organization Can be the organization's ID or name + */ + getOrganization = async ( + organization: string, + ): Promise => { + const response = await this.axios.get( + `/api/v2/organizations/${organization}`, + ); + + return response.data; + }; + + /** + * @param organization Can be the organization's ID or name + */ + getOrganizationMembers = async (organization: string) => { + const response = await this.axios.get< + TypesGen.OrganizationMemberWithUserData[] + >(`/api/v2/organizations/${organization}/members`); + + return response.data; + }; + + /** + * @param organization Can be the organization's ID or name + */ + getOrganizationRoles = async (organization: string) => { + const response = await this.axios.get( + `/api/v2/organizations/${organization}/members/roles`, + ); + + return response.data; + }; + + /** + * @param organization Can be the organization's ID or name + */ + updateOrganizationMemberRoles = async ( + organization: string, + userId: string, + roles: TypesGen.SlimRole["name"][], + ): Promise => { + const response = await this.axios.put( + `/api/v2/organizations/${organization}/members/${userId}/roles`, + { roles }, + ); + + return response.data; + }; + + /** + * @param organization Can be the organization's ID or name + */ + createOrganizationRole = async ( + organization: string, + role: TypesGen.Role, + ): Promise => { + const response = await this.axios.post( + `/api/v2/organizations/${organization}/members/roles`, + role, + ); + + return response.data; + }; + + /** + * @param organization Can be the organization's ID or name + */ + updateOrganizationRole = async ( + organization: string, + role: TypesGen.Role, + ): Promise => { + const response = await this.axios.put( + `/api/v2/organizations/${organization}/members/roles`, + role, + ); + + return response.data; + }; + + /** + * @param organization Can be the organization's ID or name + */ + deleteOrganizationRole = async (organization: string, roleName: string) => { + await this.axios.delete( + `/api/v2/organizations/${organization}/members/roles/${roleName}`, + ); + }; + + /** + * @param organization Can be the organization's ID or name + */ + addOrganizationMember = async (organization: string, userId: string) => { + const response = await this.axios.post( + `/api/v2/organizations/${organization}/members/${userId}`, + ); + + return response.data; + }; + + /** + * @param organization Can be the organization's ID or name + */ + removeOrganizationMember = async (organization: string, userId: string) => { + await this.axios.delete( + `/api/v2/organizations/${organization}/members/${userId}`, + ); + }; + + getOrganizations = async (): Promise => { + const response = await this.axios.get( + "/api/v2/organizations", + ); + return response.data; + }; + + getMyOrganizations = async (): Promise => { + const response = await this.axios.get( + "/api/v2/users/me/organizations", + ); + return response.data; + }; + + /** + * @param organization Can be the organization's ID or name + */ + getProvisionerDaemonsByOrganization = async ( + organization: string, + ): Promise => { + const response = await this.axios.get( + `/api/v2/organizations/${organization}/provisionerdaemons`, + ); + return response.data; + }; + + getTemplate = async (templateId: string): Promise => { + const response = await this.axios.get( + `/api/v2/templates/${templateId}`, + ); + + return response.data; + }; + + getTemplates = async ( + options?: GetTemplatesOptions | GetTemplatesQuery, + ): Promise => { + const params = normalizeGetTemplatesOptions(options); + const response = await this.axios.get( + "/api/v2/templates", + { params }, + ); + + return response.data; + }; + + /** + * @param organization Can be the organization's ID or name + */ + getTemplatesByOrganization = async ( + organization: string, + options?: GetTemplatesOptions, + ): Promise => { + const params = normalizeGetTemplatesOptions(options); + const response = await this.axios.get( + `/api/v2/organizations/${organization}/templates`, + { params }, + ); + + return response.data; + }; + + /** + * @param organization Can be the organization's ID or name + */ + getTemplateByName = async ( + organization: string, + name: string, + ): Promise => { + const response = await this.axios.get( + `/api/v2/organizations/${organization}/templates/${name}`, + ); + + return response.data; + }; + + getTemplateVersion = async ( + versionId: string, + ): Promise => { + const response = await this.axios.get( + `/api/v2/templateversions/${versionId}`, + ); + + return response.data; + }; + + getTemplateVersionResources = async ( + versionId: string, + ): Promise => { + const response = await this.axios.get( + `/api/v2/templateversions/${versionId}/resources`, + ); + + return response.data; + }; + + getTemplateVersionVariables = async ( + versionId: string, + ): Promise => { + // Defined as separate variable to avoid wonky Prettier formatting because + // the type definition is so long + type VerArray = TypesGen.TemplateVersionVariable[]; + + const response = await this.axios.get( + `/api/v2/templateversions/${versionId}/variables`, + ); + + return response.data; + }; + + getTemplateVersions = async ( + templateId: string, + ): Promise => { + const response = await this.axios.get( + `/api/v2/templates/${templateId}/versions`, + ); + return response.data; + }; + + /** + * @param organization Can be the organization's ID or name + */ + getTemplateVersionByName = async ( + organization: string, + templateName: string, + versionName: string, + ): Promise => { + const response = await this.axios.get( + `/api/v2/organizations/${organization}/templates/${templateName}/versions/${versionName}`, + ); + + return response.data; + }; + + /** + * @param organization Can be the organization's ID or name + */ + getPreviousTemplateVersionByName = async ( + organization: string, + templateName: string, + versionName: string, + ) => { + try { + const response = await this.axios.get( + `/api/v2/organizations/${organization}/templates/${templateName}/versions/${versionName}/previous`, + ); + + return response.data; + } catch (error) { + // When there is no previous version, like the first version of a + // template, the API returns 404 so in this case we can safely return + // undefined + const is404 = + isAxiosError(error) && error.response && error.response.status === 404; + + if (is404) { + return undefined; + } + + throw error; + } + }; + + /** + * @param organization Can be the organization's ID or name + */ + createTemplateVersion = async ( + organization: string, + data: TypesGen.CreateTemplateVersionRequest, + ): Promise => { + const response = await this.axios.post( + `/api/v2/organizations/${organization}/templateversions`, + data, + ); + + return response.data; + }; + + getTemplateVersionExternalAuth = async ( + versionId: string, + ): Promise => { + const response = await this.axios.get( + `/api/v2/templateversions/${versionId}/external-auth`, + ); + + return response.data; + }; + + getTemplateVersionRichParameters = async ( + versionId: string, + ): Promise => { + const response = await this.axios.get( + `/api/v2/templateversions/${versionId}/rich-parameters`, + ); + return response.data; + }; + + /** + * @param organization Can be the organization's ID or name + */ + createTemplate = async ( + organization: string, + data: TypesGen.CreateTemplateRequest, + ): Promise => { + const response = await this.axios.post( + `/api/v2/organizations/${organization}/templates`, + data, + ); + + return response.data; + }; + + updateActiveTemplateVersion = async ( + templateId: string, + data: TypesGen.UpdateActiveTemplateVersion, + ) => { + const response = await this.axios.patch( + `/api/v2/templates/${templateId}/versions`, + data, + ); + return response.data; + }; + + patchTemplateVersion = async ( + templateVersionId: string, + data: TypesGen.PatchTemplateVersionRequest, + ) => { + const response = await this.axios.patch( + `/api/v2/templateversions/${templateVersionId}`, + data, + ); + + return response.data; + }; + + archiveTemplateVersion = async (templateVersionId: string) => { + const response = await this.axios.post( + `/api/v2/templateversions/${templateVersionId}/archive`, + ); + + return response.data; + }; + + unarchiveTemplateVersion = async (templateVersionId: string) => { + const response = await this.axios.post( + `/api/v2/templateversions/${templateVersionId}/unarchive`, + ); + return response.data; + }; + + updateTemplateMeta = async ( + templateId: string, + data: TypesGen.UpdateTemplateMeta, + ): Promise => { + const response = await this.axios.patch( + `/api/v2/templates/${templateId}`, + data, + ); + + // On 304 response there is no data payload. + if (response.status === 304) { + return null; + } + + return response.data; + }; + + deleteTemplate = async (templateId: string): Promise => { + const response = await this.axios.delete( + `/api/v2/templates/${templateId}`, + ); + + return response.data; + }; + + getWorkspace = async ( + workspaceId: string, + params?: TypesGen.WorkspaceOptions, + ): Promise => { + const response = await this.axios.get( + `/api/v2/workspaces/${workspaceId}`, + { params }, + ); + + return response.data; + }; + + getWorkspaces = async ( + options: TypesGen.WorkspacesRequest, + ): Promise => { + const url = getURLWithSearchParams("/api/v2/workspaces", options); + const response = await this.axios.get(url); + return response.data; + }; + + getWorkspaceByOwnerAndName = async ( + username = "me", + workspaceName: string, + params?: TypesGen.WorkspaceOptions, + ): Promise => { + const response = await this.axios.get( + `/api/v2/users/${username}/workspace/${workspaceName}`, + { params }, + ); + + return response.data; + }; + + getWorkspaceBuildByNumber = async ( + username = "me", + workspaceName: string, + buildNumber: number, + ): Promise => { + const response = await this.axios.get( + `/api/v2/users/${username}/workspace/${workspaceName}/builds/${buildNumber}`, + ); + + return response.data; + }; + + waitForBuild = (build: TypesGen.WorkspaceBuild) => { + return new Promise((res, reject) => { + void (async () => { + let latestJobInfo: TypesGen.ProvisionerJob | undefined = undefined; + + while ( + !["succeeded", "canceled"].some((status) => + latestJobInfo?.status.includes(status), + ) + ) { + const { job } = await this.getWorkspaceBuildByNumber( + build.workspace_owner_name, + build.workspace_name, + build.build_number, + ); + + latestJobInfo = job; + if (latestJobInfo.status === "failed") { + return reject(latestJobInfo); + } + + await delay(1000); + } + + return res(latestJobInfo); + })(); + }); + }; + + postWorkspaceBuild = async ( + workspaceId: string, + data: TypesGen.CreateWorkspaceBuildRequest, + ): Promise => { + const response = await this.axios.post( + `/api/v2/workspaces/${workspaceId}/builds`, + data, + ); + + return response.data; + }; + + startWorkspace = ( + workspaceId: string, + templateVersionId: string, + logLevel?: TypesGen.ProvisionerLogLevel, + buildParameters?: TypesGen.WorkspaceBuildParameter[], + ) => { + return this.postWorkspaceBuild(workspaceId, { + transition: "start", + template_version_id: templateVersionId, + log_level: logLevel, + rich_parameter_values: buildParameters, + }); + }; + + stopWorkspace = ( + workspaceId: string, + logLevel?: TypesGen.ProvisionerLogLevel, + ) => { + return this.postWorkspaceBuild(workspaceId, { + transition: "stop", + log_level: logLevel, + }); + }; + + deleteWorkspace = (workspaceId: string, options?: DeleteWorkspaceOptions) => { + return this.postWorkspaceBuild(workspaceId, { + transition: "delete", + ...options, + }); + }; + + cancelWorkspaceBuild = async ( + workspaceBuildId: TypesGen.WorkspaceBuild["id"], + ): Promise => { + const response = await this.axios.patch( + `/api/v2/workspacebuilds/${workspaceBuildId}/cancel`, + ); + + return response.data; + }; + + updateWorkspaceDormancy = async ( + workspaceId: string, + dormant: boolean, + ): Promise => { + const data: TypesGen.UpdateWorkspaceDormancy = { dormant }; + const response = await this.axios.put( + `/api/v2/workspaces/${workspaceId}/dormant`, + data, + ); + + return response.data; + }; + + updateWorkspaceAutomaticUpdates = async ( + workspaceId: string, + automaticUpdates: TypesGen.AutomaticUpdates, + ): Promise => { + const req: TypesGen.UpdateWorkspaceAutomaticUpdatesRequest = { + automatic_updates: automaticUpdates, + }; + + const response = await this.axios.put( + `/api/v2/workspaces/${workspaceId}/autoupdates`, + req, + ); + + return response.data; + }; + + restartWorkspace = async ({ + workspace, + buildParameters, + }: RestartWorkspaceParameters): Promise => { + const stopBuild = await this.stopWorkspace(workspace.id); + const awaitedStopBuild = await this.waitForBuild(stopBuild); + + // If the restart is canceled halfway through, make sure we bail + if (awaitedStopBuild?.status === "canceled") { + return; + } + + const startBuild = await this.startWorkspace( + workspace.id, + workspace.latest_build.template_version_id, + undefined, + buildParameters, + ); + + await this.waitForBuild(startBuild); + }; + + cancelTemplateVersionBuild = async ( + templateVersionId: TypesGen.TemplateVersion["id"], + ): Promise => { + const response = await this.axios.patch( + `/api/v2/templateversions/${templateVersionId}/cancel`, + ); + + return response.data; + }; + + createUser = async ( + user: TypesGen.CreateUserRequest, + ): Promise => { + const response = await this.axios.post( + "/api/v2/users", + user, + ); + + return response.data; + }; + + createWorkspace = async ( + userId = "me", + workspace: TypesGen.CreateWorkspaceRequest, + ): Promise => { + const response = await this.axios.post( + `/api/v2/users/${userId}/workspaces`, + workspace, + ); + + return response.data; + }; + + patchWorkspace = async ( + workspaceId: string, + data: TypesGen.UpdateWorkspaceRequest, + ): Promise => { + await this.axios.patch(`/api/v2/workspaces/${workspaceId}`, data); + }; + + getBuildInfo = async (): Promise => { + const response = await this.axios.get("/api/v2/buildinfo"); + return response.data; + }; + + getUpdateCheck = async (): Promise => { + const response = await this.axios.get("/api/v2/updatecheck"); + return response.data; + }; + + putWorkspaceAutostart = async ( + workspaceID: string, + autostart: TypesGen.UpdateWorkspaceAutostartRequest, + ): Promise => { + const payload = JSON.stringify(autostart); + await this.axios.put( + `/api/v2/workspaces/${workspaceID}/autostart`, + payload, + { headers: { ...BASE_CONTENT_TYPE_JSON } }, + ); + }; + + putWorkspaceAutostop = async ( + workspaceID: string, + ttl: TypesGen.UpdateWorkspaceTTLRequest, + ): Promise => { + const payload = JSON.stringify(ttl); + await this.axios.put(`/api/v2/workspaces/${workspaceID}/ttl`, payload, { + headers: { ...BASE_CONTENT_TYPE_JSON }, + }); + }; + + updateProfile = async ( + userId: string, + data: TypesGen.UpdateUserProfileRequest, + ): Promise => { + const response = await this.axios.put( + `/api/v2/users/${userId}/profile`, + data, + ); + return response.data; + }; + + updateAppearanceSettings = async ( + userId: string, + data: TypesGen.UpdateUserAppearanceSettingsRequest, + ): Promise => { + const response = await this.axios.put( + `/api/v2/users/${userId}/appearance`, + data, + ); + return response.data; + }; + + getUserQuietHoursSchedule = async ( + userId: TypesGen.User["id"], + ): Promise => { + const response = await this.axios.get( + `/api/v2/users/${userId}/quiet-hours`, + ); + return response.data; + }; + + updateUserQuietHoursSchedule = async ( + userId: TypesGen.User["id"], + data: TypesGen.UpdateUserQuietHoursScheduleRequest, + ): Promise => { + const response = await this.axios.put( + `/api/v2/users/${userId}/quiet-hours`, + data, + ); + + return response.data; + }; + + activateUser = async ( + userId: TypesGen.User["id"], + ): Promise => { + const response = await this.axios.put( + `/api/v2/users/${userId}/status/activate`, + ); + return response.data; + }; + + suspendUser = async (userId: TypesGen.User["id"]): Promise => { + const response = await this.axios.put( + `/api/v2/users/${userId}/status/suspend`, + ); + + return response.data; + }; + + deleteUser = async (userId: TypesGen.User["id"]): Promise => { + await this.axios.delete(`/api/v2/users/${userId}`); + }; + + // API definition: + // https://github.com/coder/coder/blob/db665e7261f3c24a272ccec48233a3e276878239/coderd/users.go#L33-L53 + hasFirstUser = async (): Promise => { + try { + // If it is success, it is true + await this.axios.get("/api/v2/users/first"); + return true; + } catch (error) { + // If it returns a 404, it is false + if (isAxiosError(error) && error.response?.status === 404) { + return false; + } + + throw error; + } + }; + + createFirstUser = async ( + req: TypesGen.CreateFirstUserRequest, + ): Promise => { + const response = await this.axios.post("/api/v2/users/first", req); + return response.data; + }; + + updateUserPassword = async ( + userId: TypesGen.User["id"], + updatePassword: TypesGen.UpdateUserPasswordRequest, + ): Promise => { + await this.axios.put(`/api/v2/users/${userId}/password`, updatePassword); + }; + + getRoles = async (): Promise> => { + const response = await this.axios.get( + "/api/v2/users/roles", + ); + + return response.data; + }; + + updateUserRoles = async ( + roles: TypesGen.SlimRole["name"][], + userId: TypesGen.User["id"], + ): Promise => { + const response = await this.axios.put( + `/api/v2/users/${userId}/roles`, + { roles }, + ); + + return response.data; + }; + + getUserSSHKey = async (userId = "me"): Promise => { + const response = await this.axios.get( + `/api/v2/users/${userId}/gitsshkey`, + ); + + return response.data; + }; + + regenerateUserSSHKey = async (userId = "me"): Promise => { + const response = await this.axios.put( + `/api/v2/users/${userId}/gitsshkey`, + ); + + return response.data; + }; + + getWorkspaceBuilds = async ( + workspaceId: string, + req?: TypesGen.WorkspaceBuildsRequest, + ) => { + const response = await this.axios.get( + getURLWithSearchParams(`/api/v2/workspaces/${workspaceId}/builds`, req), + ); + + return response.data; + }; + + getWorkspaceBuildLogs = async ( + buildId: string, + ): Promise => { + const response = await this.axios.get( + `/api/v2/workspacebuilds/${buildId}/logs`, + ); + + return response.data; + }; + + getWorkspaceAgentLogs = async ( + agentID: string, + ): Promise => { + const response = await this.axios.get( + `/api/v2/workspaceagents/${agentID}/logs`, + ); + + return response.data; + }; + + putWorkspaceExtension = async ( + workspaceId: string, + newDeadline: dayjs.Dayjs, + ): Promise => { + await this.axios.put(`/api/v2/workspaces/${workspaceId}/extend`, { + deadline: newDeadline, + }); + }; + + refreshEntitlements = async (): Promise => { + await this.axios.post("/api/v2/licenses/refresh-entitlements"); + }; + + getEntitlements = async (): Promise => { + try { + const response = await this.axios.get( + "/api/v2/entitlements", + ); + + return response.data; + } catch (ex) { + if (isAxiosError(ex) && ex.response?.status === 404) { + return { + errors: [], + features: withDefaultFeatures({}), + has_license: false, + require_telemetry: false, + trial: false, + warnings: [], + refreshed_at: "", + }; + } + throw ex; + } + }; + + getExperiments = async (): Promise => { + try { + const response = await this.axios.get( + "/api/v2/experiments", + ); + + return response.data; + } catch (error) { + if (isAxiosError(error) && error.response?.status === 404) { + return []; + } + + throw error; + } + }; + + getAvailableExperiments = + async (): Promise => { + try { + const response = await this.axios.get("/api/v2/experiments/available"); + + return response.data; + } catch (error) { + if (isAxiosError(error) && error.response?.status === 404) { + return { safe: [] }; + } + throw error; + } + }; + + getExternalAuthProvider = async ( + provider: string, + ): Promise => { + const res = await this.axios.get(`/api/v2/external-auth/${provider}`); + return res.data; + }; + + getExternalAuthDevice = async ( + provider: string, + ): Promise => { + const resp = await this.axios.get( + `/api/v2/external-auth/${provider}/device`, + ); + return resp.data; + }; + + exchangeExternalAuthDevice = async ( + provider: string, + req: TypesGen.ExternalAuthDeviceExchange, + ): Promise => { + const resp = await this.axios.post( + `/api/v2/external-auth/${provider}/device`, + req, + ); + + return resp.data; + }; + + getUserExternalAuthProviders = + async (): Promise => { + const resp = await this.axios.get("/api/v2/external-auth"); + return resp.data; + }; + + unlinkExternalAuthProvider = async (provider: string): Promise => { + const resp = await this.axios.delete(`/api/v2/external-auth/${provider}`); + return resp.data; + }; + + getOAuth2ProviderApps = async ( + filter?: TypesGen.OAuth2ProviderAppFilter, + ): Promise => { + const params = filter?.user_id + ? new URLSearchParams({ user_id: filter.user_id }).toString() + : ""; + + const resp = await this.axios.get(`/api/v2/oauth2-provider/apps?${params}`); + return resp.data; + }; + + getOAuth2ProviderApp = async ( + id: string, + ): Promise => { + const resp = await this.axios.get(`/api/v2/oauth2-provider/apps/${id}`); + return resp.data; + }; + + postOAuth2ProviderApp = async ( + data: TypesGen.PostOAuth2ProviderAppRequest, + ): Promise => { + const response = await this.axios.post( + "/api/v2/oauth2-provider/apps", + data, + ); + return response.data; + }; + + putOAuth2ProviderApp = async ( + id: string, + data: TypesGen.PutOAuth2ProviderAppRequest, + ): Promise => { + const response = await this.axios.put( + `/api/v2/oauth2-provider/apps/${id}`, + data, + ); + return response.data; + }; + + deleteOAuth2ProviderApp = async (id: string): Promise => { + await this.axios.delete(`/api/v2/oauth2-provider/apps/${id}`); + }; + + getOAuth2ProviderAppSecrets = async ( + id: string, + ): Promise => { + const resp = await this.axios.get( + `/api/v2/oauth2-provider/apps/${id}/secrets`, + ); + return resp.data; + }; + + postOAuth2ProviderAppSecret = async ( + id: string, + ): Promise => { + const resp = await this.axios.post( + `/api/v2/oauth2-provider/apps/${id}/secrets`, + ); + return resp.data; + }; + + deleteOAuth2ProviderAppSecret = async ( + appId: string, + secretId: string, + ): Promise => { + await this.axios.delete( + `/api/v2/oauth2-provider/apps/${appId}/secrets/${secretId}`, + ); + }; + + revokeOAuth2ProviderApp = async (appId: string): Promise => { + await this.axios.delete(`/oauth2/tokens?client_id=${appId}`); + }; + + getAuditLogs = async ( + options: TypesGen.AuditLogsRequest, + ): Promise => { + const url = getURLWithSearchParams("/api/v2/audit", options); + const response = await this.axios.get(url); + return response.data; + }; + + getTemplateDAUs = async ( + templateId: string, + ): Promise => { + const response = await this.axios.get( + `/api/v2/templates/${templateId}/daus`, + ); + + return response.data; + }; + + getDeploymentDAUs = async ( + // Default to user's local timezone. + // As /api/v2/insights/daus only accepts whole-number values for tz_offset + // we truncate the tz offset down to the closest hour. + offset = Math.trunc(new Date().getTimezoneOffset() / 60), + ): Promise => { + const response = await this.axios.get( + `/api/v2/insights/daus?tz_offset=${offset}`, + ); + + return response.data; + }; + + getTemplateACLAvailable = async ( + templateId: string, + options: TypesGen.UsersRequest, + ): Promise => { + const url = getURLWithSearchParams( + `/api/v2/templates/${templateId}/acl/available`, + options, + ).toString(); + + const response = await this.axios.get(url); + return response.data; + }; + + getTemplateACL = async ( + templateId: string, + ): Promise => { + const response = await this.axios.get( + `/api/v2/templates/${templateId}/acl`, + ); + + return response.data; + }; + + updateTemplateACL = async ( + templateId: string, + data: TypesGen.UpdateTemplateACL, + ): Promise<{ message: string }> => { + const response = await this.axios.patch( + `/api/v2/templates/${templateId}/acl`, + data, + ); + + return response.data; + }; + + getApplicationsHost = async (): Promise => { + const response = await this.axios.get("/api/v2/applications/host"); + return response.data; + }; + + /** + * @param organization Can be the organization's ID or name + */ + getGroups = async (organization: string): Promise => { + const response = await this.axios.get( + `/api/v2/organizations/${organization}/groups`, + ); + + return response.data; + }; + + /** + * @param organization Can be the organization's ID or name + */ + createGroup = async ( + organization: string, + data: TypesGen.CreateGroupRequest, + ): Promise => { + const response = await this.axios.post( + `/api/v2/organizations/${organization}/groups`, + data, + ); + return response.data; + }; + + /** + * @param organization Can be the organization's ID or name + */ + getGroup = async ( + organization: string, + groupName: string, + ): Promise => { + const response = await this.axios.get( + `/api/v2/organizations/${organization}/groups/${groupName}`, + ); + return response.data; + }; + + patchGroup = async ( + groupId: string, + data: TypesGen.PatchGroupRequest, + ): Promise => { + const response = await this.axios.patch(`/api/v2/groups/${groupId}`, data); + return response.data; + }; + + addMember = async (groupId: string, userId: string) => { + return this.patchGroup(groupId, { + name: "", + add_users: [userId], + remove_users: [], + }); + }; + + removeMember = async (groupId: string, userId: string) => { + return this.patchGroup(groupId, { + name: "", + display_name: "", + add_users: [], + remove_users: [userId], + }); + }; + + deleteGroup = async (groupId: string): Promise => { + await this.axios.delete(`/api/v2/groups/${groupId}`); + }; + + getWorkspaceQuota = async ( + username: string, + ): Promise => { + const response = await this.axios.get( + `/api/v2/workspace-quota/${encodeURIComponent(username)}`, + ); + return response.data; + }; + + getAgentListeningPorts = async ( + agentID: string, + ): Promise => { + const response = await this.axios.get( + `/api/v2/workspaceagents/${agentID}/listening-ports`, + ); + return response.data; + }; + + getWorkspaceAgentSharedPorts = async ( + workspaceID: string, + ): Promise => { + const response = await this.axios.get( + `/api/v2/workspaces/${workspaceID}/port-share`, + ); + return response.data; + }; + + upsertWorkspaceAgentSharedPort = async ( + workspaceID: string, + req: TypesGen.UpsertWorkspaceAgentPortShareRequest, + ): Promise => { + const response = await this.axios.post( + `/api/v2/workspaces/${workspaceID}/port-share`, + req, + ); + return response.data; + }; + + deleteWorkspaceAgentSharedPort = async ( + workspaceID: string, + req: TypesGen.DeleteWorkspaceAgentPortShareRequest, + ): Promise => { + const response = await this.axios.delete( + `/api/v2/workspaces/${workspaceID}/port-share`, + { data: req }, + ); + + return response.data; + }; + + // getDeploymentSSHConfig is used by the VSCode-Extension. + getDeploymentSSHConfig = async (): Promise => { + const response = await this.axios.get("/api/v2/deployment/ssh"); + return response.data; + }; + + getDeploymentConfig = async (): Promise => { + const response = await this.axios.get("/api/v2/deployment/config"); + return response.data; + }; + + getDeploymentStats = async (): Promise => { + const response = await this.axios.get("/api/v2/deployment/stats"); + return response.data; + }; + + getReplicas = async (): Promise => { + const response = await this.axios.get("/api/v2/replicas"); + return response.data; + }; + + getFile = async (fileId: string): Promise => { + const response = await this.axios.get( + `/api/v2/files/${fileId}`, + { responseType: "arraybuffer" }, + ); + + return response.data; + }; + + getWorkspaceProxyRegions = async (): Promise< + TypesGen.RegionsResponse + > => { + const response = + await this.axios.get>( + "/api/v2/regions", + ); + + return response.data; + }; + + getWorkspaceProxies = async (): Promise< + TypesGen.RegionsResponse + > => { + const response = await this.axios.get< + TypesGen.RegionsResponse + >("/api/v2/workspaceproxies"); + + return response.data; + }; + + createWorkspaceProxy = async ( + b: TypesGen.CreateWorkspaceProxyRequest, + ): Promise => { + const response = await this.axios.post("/api/v2/workspaceproxies", b); + return response.data; + }; + + getAppearance = async (): Promise => { + try { + const response = await this.axios.get("/api/v2/appearance"); + return response.data || {}; + } catch (ex) { + if (isAxiosError(ex) && ex.response?.status === 404) { + return { + application_name: "", + logo_url: "", + announcement_banners: [], + service_banner: { + enabled: false, + }, + }; + } + + throw ex; + } + }; + + updateAppearance = async ( + b: TypesGen.AppearanceConfig, + ): Promise => { + const response = await this.axios.put("/api/v2/appearance", b); + return response.data; + }; + + /** + * @param organization Can be the organization's ID or name + */ + getTemplateExamples = async (): Promise => { + const response = await this.axios.get("/api/v2/templates/examples"); + + return response.data; + }; + + uploadFile = async (file: File): Promise => { + const response = await this.axios.post("/api/v2/files", file, { + headers: { "Content-Type": "application/x-tar" }, + }); + + return response.data; + }; + + getTemplateVersionLogs = async ( + versionId: string, + ): Promise => { + const response = await this.axios.get( + `/api/v2/templateversions/${versionId}/logs`, + ); + return response.data; + }; + + updateWorkspaceVersion = async ( + workspace: TypesGen.Workspace, + ): Promise => { + const template = await this.getTemplate(workspace.template_id); + return this.startWorkspace(workspace.id, template.active_version_id); + }; + + getWorkspaceBuildParameters = async ( + workspaceBuildId: TypesGen.WorkspaceBuild["id"], + ): Promise => { + const response = await this.axios.get( + `/api/v2/workspacebuilds/${workspaceBuildId}/parameters`, + ); + + return response.data; + }; + + getLicenses = async (): Promise => { + const response = await this.axios.get("/api/v2/licenses"); + return response.data; + }; + + createLicense = async ( + data: TypesGen.AddLicenseRequest, + ): Promise => { + const response = await this.axios.post("/api/v2/licenses", data); + return response.data; + }; + + removeLicense = async (licenseId: number): Promise => { + await this.axios.delete(`/api/v2/licenses/${licenseId}`); + }; + + /** Steps to change the workspace version + * - Get the latest template to access the latest active version + * - Get the current build parameters + * - Get the template parameters + * - Update the build parameters and check if there are missed parameters for + * the new version + * - If there are missing parameters raise an error + * - Create a build with the version and updated build parameters + */ + changeWorkspaceVersion = async ( + workspace: TypesGen.Workspace, + templateVersionId: string, + newBuildParameters: TypesGen.WorkspaceBuildParameter[] = [], + ): Promise => { + const [currentBuildParameters, templateParameters] = await Promise.all([ + this.getWorkspaceBuildParameters(workspace.latest_build.id), + this.getTemplateVersionRichParameters(templateVersionId), + ]); + + const missingParameters = getMissingParameters( + currentBuildParameters, + newBuildParameters, + templateParameters, + ); + + if (missingParameters.length > 0) { + throw new MissingBuildParameters(missingParameters, templateVersionId); + } + + return this.postWorkspaceBuild(workspace.id, { + transition: "start", + template_version_id: templateVersionId, + rich_parameter_values: newBuildParameters, + }); + }; + + /** Steps to update the workspace + * - Get the latest template to access the latest active version + * - Get the current build parameters + * - Get the template parameters + * - Update the build parameters and check if there are missed parameters for + * the newest version + * - If there are missing parameters raise an error + * - Create a build with the latest version and updated build parameters + */ + updateWorkspace = async ( + workspace: TypesGen.Workspace, + newBuildParameters: TypesGen.WorkspaceBuildParameter[] = [], + ): Promise => { + const [template, oldBuildParameters] = await Promise.all([ + this.getTemplate(workspace.template_id), + this.getWorkspaceBuildParameters(workspace.latest_build.id), + ]); + + const activeVersionId = template.active_version_id; + const templateParameters = + await this.getTemplateVersionRichParameters(activeVersionId); + + const missingParameters = getMissingParameters( + oldBuildParameters, + newBuildParameters, + templateParameters, + ); + + if (missingParameters.length > 0) { + throw new MissingBuildParameters(missingParameters, activeVersionId); + } + + return this.postWorkspaceBuild(workspace.id, { + transition: "start", + template_version_id: activeVersionId, + rich_parameter_values: newBuildParameters, + }); + }; + + getWorkspaceResolveAutostart = async ( + workspaceId: string, + ): Promise => { + const response = await this.axios.get( + `/api/v2/workspaces/${workspaceId}/resolve-autostart`, + ); + return response.data; + }; + + issueReconnectingPTYSignedToken = async ( + params: TypesGen.IssueReconnectingPTYSignedTokenRequest, + ): Promise => { + const response = await this.axios.post( + "/api/v2/applications/reconnecting-pty-signed-token", + params, + ); + + return response.data; + }; + + getWorkspaceParameters = async (workspace: TypesGen.Workspace) => { + const latestBuild = workspace.latest_build; + const [templateVersionRichParameters, buildParameters] = await Promise.all([ + this.getTemplateVersionRichParameters(latestBuild.template_version_id), + this.getWorkspaceBuildParameters(latestBuild.id), + ]); + + return { + templateVersionRichParameters, + buildParameters, + }; + }; + + getInsightsUserLatency = async ( + filters: InsightsParams, + ): Promise => { + const params = new URLSearchParams(filters); + const response = await this.axios.get( + `/api/v2/insights/user-latency?${params}`, + ); + + return response.data; + }; + + getInsightsUserActivity = async ( + filters: InsightsParams, + ): Promise => { + const params = new URLSearchParams(filters); + const response = await this.axios.get( + `/api/v2/insights/user-activity?${params}`, + ); + + return response.data; + }; + + getInsightsTemplate = async ( + params: InsightsTemplateParams, + ): Promise => { + const searchParams = new URLSearchParams(params); + const response = await this.axios.get( + `/api/v2/insights/templates?${searchParams}`, + ); + + return response.data; + }; + + getHealth = async (force = false) => { + const params = new URLSearchParams({ force: force.toString() }); + const response = await this.axios.get( + `/api/v2/debug/health?${params}`, + ); + return response.data; + }; + + getHealthSettings = async (): Promise => { + const res = await this.axios.get( + "/api/v2/debug/health/settings", + ); + + return res.data; + }; + + updateHealthSettings = async (data: TypesGen.UpdateHealthSettings) => { + const response = await this.axios.put( + "/api/v2/debug/health/settings", + data, + ); + + return response.data; + }; + + putFavoriteWorkspace = async (workspaceID: string) => { + await this.axios.put(`/api/v2/workspaces/${workspaceID}/favorite`); + }; + + deleteFavoriteWorkspace = async (workspaceID: string) => { + await this.axios.delete(`/api/v2/workspaces/${workspaceID}/favorite`); + }; + + getJFrogXRayScan = async (options: GetJFrogXRayScanParams) => { + const searchParams = new URLSearchParams({ + workspace_id: options.workspaceId, + agent_id: options.agentId, + }); + + try { + const res = await this.axios.get( + `/api/v2/integrations/jfrog/xray-scan?${searchParams}`, + ); + + return res.data; + } catch (error) { + if (isAxiosError(error) && error.response?.status === 404) { + // react-query library does not allow undefined to be returned as a + // query result + return null; + } + + throw error; + } + }; + + postWorkspaceUsage = async ( + workspaceID: string, + options: PostWorkspaceUsageRequest, + ) => { + const response = await this.axios.post( + `/api/v2/workspaces/${workspaceID}/usage`, + options, + ); + + return response.data; + }; + + getUserNotificationPreferences = async (userId: string) => { + const res = await this.axios.get( + `/api/v2/users/${userId}/notifications/preferences`, + ); + return res.data ?? []; + }; + + putUserNotificationPreferences = async ( + userId: string, + req: TypesGen.UpdateUserNotificationPreferences, + ) => { + const res = await this.axios.put( + `/api/v2/users/${userId}/notifications/preferences`, + req, + ); + return res.data; + }; + + getSystemNotificationTemplates = async () => { + const res = await this.axios.get( + "/api/v2/notifications/templates/system", + ); + return res.data; + }; + + getNotificationDispatchMethods = async () => { + const res = await this.axios.get( + "/api/v2/notifications/dispatch-methods", + ); + return res.data; + }; + + updateNotificationTemplateMethod = async ( + templateId: string, + req: TypesGen.UpdateNotificationTemplateMethod, + ) => { + const res = await this.axios.put( + `/api/v2/notifications/templates/${templateId}/method`, + req, + ); + return res.data; + }; } // This is a hard coded CSRF token/cookie pair for local development. In prod, @@ -2123,82 +2123,82 @@ class ApiMethods { // static files, so this is the 'hack' to make local development work with // remote apis. The CSRF cookie for this token is "JXm9hOUdZctWt0ZZGAy9xiS/gxMKYOThdxjjMnMUyn4=" const csrfToken = - "KNKvagCBEHZK7ihe2t7fj6VeJ0UyTDco1yVUJE8N06oNqxLu5Zx1vRxZbgfC0mJJgeGkVjgs08mgPbcWPBkZ1A=="; + "KNKvagCBEHZK7ihe2t7fj6VeJ0UyTDco1yVUJE8N06oNqxLu5Zx1vRxZbgfC0mJJgeGkVjgs08mgPbcWPBkZ1A=="; // Always attach CSRF token to all requests. In puppeteer the document is // undefined. In those cases, just do nothing. const tokenMetadataElement = - typeof document !== "undefined" - ? document.head.querySelector('meta[property="csrf-token"]') - : null; + typeof document !== "undefined" + ? document.head.querySelector('meta[property="csrf-token"]') + : null; function getConfiguredAxiosInstance(): AxiosInstance { - const instance = globalAxios.create(); + const instance = globalAxios.create(); - // Adds 304 for the default axios validateStatus function - // https://github.com/axios/axios#handling-errors Check status here - // https://httpstatusdogs.com/ - instance.defaults.validateStatus = (status) => { - return (status >= 200 && status < 300) || status === 304; - }; + // Adds 304 for the default axios validateStatus function + // https://github.com/axios/axios#handling-errors Check status here + // https://httpstatusdogs.com/ + instance.defaults.validateStatus = (status) => { + return (status >= 200 && status < 300) || status === 304; + }; - const metadataIsAvailable = - tokenMetadataElement !== null && - tokenMetadataElement.getAttribute("content") !== null; + const metadataIsAvailable = + tokenMetadataElement !== null && + tokenMetadataElement.getAttribute("content") !== null; - if (metadataIsAvailable) { - if (process.env.NODE_ENV === "development") { - // Development mode uses a hard-coded CSRF token - instance.defaults.headers.common["X-CSRF-TOKEN"] = csrfToken; - instance.defaults.headers.common["X-CSRF-TOKEN"] = csrfToken; - tokenMetadataElement.setAttribute("content", csrfToken); - } else { - instance.defaults.headers.common["X-CSRF-TOKEN"] = - tokenMetadataElement.getAttribute("content") ?? ""; - } - } else { - // Do not write error logs if we are in a FE unit test. - if (process.env.JEST_WORKER_ID === undefined) { - console.error("CSRF token not found"); - } - } + if (metadataIsAvailable) { + if (process.env.NODE_ENV === "development") { + // Development mode uses a hard-coded CSRF token + instance.defaults.headers.common["X-CSRF-TOKEN"] = csrfToken; + instance.defaults.headers.common["X-CSRF-TOKEN"] = csrfToken; + tokenMetadataElement.setAttribute("content", csrfToken); + } else { + instance.defaults.headers.common["X-CSRF-TOKEN"] = + tokenMetadataElement.getAttribute("content") ?? ""; + } + } else { + // Do not write error logs if we are in a FE unit test. + if (process.env.JEST_WORKER_ID === undefined) { + console.error("CSRF token not found"); + } + } - return instance; + return instance; } // Other non-API methods defined here to make it a little easier to find them. interface ClientApi extends ApiMethods { - getCsrfToken: () => string; - setSessionToken: (token: string) => void; - setHost: (host: string | undefined) => void; - getAxiosInstance: () => AxiosInstance; + getCsrfToken: () => string; + setSessionToken: (token: string) => void; + setHost: (host: string | undefined) => void; + getAxiosInstance: () => AxiosInstance; } export class Api extends ApiMethods implements ClientApi { - constructor() { - const scopedAxiosInstance = getConfiguredAxiosInstance(); - super(scopedAxiosInstance); - } + constructor() { + const scopedAxiosInstance = getConfiguredAxiosInstance(); + super(scopedAxiosInstance); + } - // As with ApiMethods, all public methods should be defined with arrow - // function syntax to ensure they can be passed around the React UI without - // losing/detaching their `this` context! + // As with ApiMethods, all public methods should be defined with arrow + // function syntax to ensure they can be passed around the React UI without + // losing/detaching their `this` context! - getCsrfToken = (): string => { - return csrfToken; - }; + getCsrfToken = (): string => { + return csrfToken; + }; - setSessionToken = (token: string): void => { - this.axios.defaults.headers.common["Coder-Session-Token"] = token; - }; + setSessionToken = (token: string): void => { + this.axios.defaults.headers.common["Coder-Session-Token"] = token; + }; - setHost = (host: string | undefined): void => { - this.axios.defaults.baseURL = host; - }; + setHost = (host: string | undefined): void => { + this.axios.defaults.baseURL = host; + }; - getAxiosInstance = (): AxiosInstance => { - return this.axios; - }; + getAxiosInstance = (): AxiosInstance => { + return this.axios; + }; } export const API = new Api(); diff --git a/site/src/api/errors.test.ts b/site/src/api/errors.test.ts index 6d1044d8ae..860f42f28e 100644 --- a/site/src/api/errors.test.ts +++ b/site/src/api/errors.test.ts @@ -1,103 +1,103 @@ import { mockApiError } from "testHelpers/entities"; import { - getErrorMessage, - getValidationErrorMessage, - isApiError, - mapApiErrorToFieldErrors, + getErrorMessage, + getValidationErrorMessage, + isApiError, + mapApiErrorToFieldErrors, } from "./errors"; describe("isApiError", () => { - it("returns true when the object is an API Error", () => { - expect( - isApiError( - mockApiError({ - message: "Invalid entry", - validations: [ - { detail: "Username is already in use", field: "username" }, - ], - }), - ), - ).toBe(true); - }); + it("returns true when the object is an API Error", () => { + expect( + isApiError( + mockApiError({ + message: "Invalid entry", + validations: [ + { detail: "Username is already in use", field: "username" }, + ], + }), + ), + ).toBe(true); + }); - it("returns false when the object is Error", () => { - expect(isApiError(new Error())).toBe(false); - }); + it("returns false when the object is Error", () => { + expect(isApiError(new Error())).toBe(false); + }); - it("returns false when the object is undefined", () => { - expect(isApiError(undefined)).toBe(false); - }); + it("returns false when the object is undefined", () => { + expect(isApiError(undefined)).toBe(false); + }); }); describe("mapApiErrorToFieldErrors", () => { - it("returns correct field errors", () => { - expect( - mapApiErrorToFieldErrors({ - message: "Invalid entry", - validations: [ - { detail: "Username is already in use", field: "username" }, - ], - }), - ).toEqual({ - username: "Username is already in use", - }); - }); + it("returns correct field errors", () => { + expect( + mapApiErrorToFieldErrors({ + message: "Invalid entry", + validations: [ + { detail: "Username is already in use", field: "username" }, + ], + }), + ).toEqual({ + username: "Username is already in use", + }); + }); }); describe("getValidationErrorMessage", () => { - it("returns multiple validation messages", () => { - expect( - getValidationErrorMessage( - mockApiError({ - message: "Invalid user search query.", - validations: [ - { - field: "status", - detail: `Query param "status" has invalid value: "inactive" is not a valid user status`, - }, - { - field: "q", - detail: `Query element "role:a:e" can only contain 1 ':'`, - }, - ], - }), - ), - ).toEqual( - `Query param "status" has invalid value: "inactive" is not a valid user status\nQuery element "role:a:e" can only contain 1 ':'`, - ); - }); + it("returns multiple validation messages", () => { + expect( + getValidationErrorMessage( + mockApiError({ + message: "Invalid user search query.", + validations: [ + { + field: "status", + detail: `Query param "status" has invalid value: "inactive" is not a valid user status`, + }, + { + field: "q", + detail: `Query element "role:a:e" can only contain 1 ':'`, + }, + ], + }), + ), + ).toEqual( + `Query param "status" has invalid value: "inactive" is not a valid user status\nQuery element "role:a:e" can only contain 1 ':'`, + ); + }); - it("non-API error returns empty validation message", () => { - expect( - getValidationErrorMessage(new Error("Invalid user search query.")), - ).toEqual(""); - }); + it("non-API error returns empty validation message", () => { + expect( + getValidationErrorMessage(new Error("Invalid user search query.")), + ).toEqual(""); + }); - it("no validations field returns empty validation message", () => { - expect( - getValidationErrorMessage( - mockApiError({ - message: "Invalid user search query.", - detail: `Query element "role:a:e" can only contain 1 ':'`, - }), - ), - ).toEqual(""); - }); + it("no validations field returns empty validation message", () => { + expect( + getValidationErrorMessage( + mockApiError({ + message: "Invalid user search query.", + detail: `Query element "role:a:e" can only contain 1 ':'`, + }), + ), + ).toEqual(""); + }); - it("returns default message for error that is empty string", () => { - expect(getErrorMessage("", "Something went wrong.")).toBe( - "Something went wrong.", - ); - }); + it("returns default message for error that is empty string", () => { + expect(getErrorMessage("", "Something went wrong.")).toBe( + "Something went wrong.", + ); + }); - it("returns default message for 404 API response", () => { - expect( - getErrorMessage( - mockApiError({ - message: "", - }), - "Something went wrong.", - ), - ).toBe("Something went wrong."); - }); + it("returns default message for 404 API response", () => { + expect( + getErrorMessage( + mockApiError({ + message: "", + }), + "Something went wrong.", + ), + ).toBe("Something went wrong."); + }); }); diff --git a/site/src/api/errors.ts b/site/src/api/errors.ts index 8f69e06fc4..51572f2940 100644 --- a/site/src/api/errors.ts +++ b/site/src/api/errors.ts @@ -1,74 +1,74 @@ import { type AxiosError, type AxiosResponse, isAxiosError } from "axios"; const Language = { - errorsByCode: { - defaultErrorCode: "Invalid value", - }, + errorsByCode: { + defaultErrorCode: "Invalid value", + }, }; export interface FieldError { - field: string; - detail: string; + field: string; + detail: string; } export type FieldErrors = Record; export interface ApiErrorResponse { - message: string; - detail?: string; - validations?: FieldError[]; + message: string; + detail?: string; + validations?: FieldError[]; } export type ApiError = AxiosError & { - response: AxiosResponse; + response: AxiosResponse; }; export const isApiError = (err: unknown): err is ApiError => { - return ( - isAxiosError(err) && - err.response !== undefined && - isApiErrorResponse(err.response.data) - ); + return ( + isAxiosError(err) && + err.response !== undefined && + isApiErrorResponse(err.response.data) + ); }; export const isApiErrorResponse = (err: unknown): err is ApiErrorResponse => { - return ( - typeof err === "object" && - err !== null && - "message" in err && - typeof err.message === "string" && - (!("detail" in err) || - err.detail === undefined || - typeof err.detail === "string") && - (!("validations" in err) || - err.validations === undefined || - Array.isArray(err.validations)) - ); + return ( + typeof err === "object" && + err !== null && + "message" in err && + typeof err.message === "string" && + (!("detail" in err) || + err.detail === undefined || + typeof err.detail === "string") && + (!("validations" in err) || + err.validations === undefined || + Array.isArray(err.validations)) + ); }; export const hasApiFieldErrors = (error: ApiError): boolean => - Array.isArray(error.response.data.validations); + Array.isArray(error.response.data.validations); export const isApiValidationError = (error: unknown): error is ApiError => { - return isApiError(error) && hasApiFieldErrors(error); + return isApiError(error) && hasApiFieldErrors(error); }; export const hasError = (error: unknown) => - error !== undefined && error !== null; + error !== undefined && error !== null; export const mapApiErrorToFieldErrors = ( - apiErrorResponse: ApiErrorResponse, + apiErrorResponse: ApiErrorResponse, ): FieldErrors => { - const result: FieldErrors = {}; + const result: FieldErrors = {}; - if (apiErrorResponse.validations) { - for (const error of apiErrorResponse.validations) { - result[error.field] = - error.detail || Language.errorsByCode.defaultErrorCode; - } - } + if (apiErrorResponse.validations) { + for (const error of apiErrorResponse.validations) { + result[error.field] = + error.detail || Language.errorsByCode.defaultErrorCode; + } + } - return result; + return result; }; /** @@ -78,22 +78,22 @@ export const mapApiErrorToFieldErrors = ( * @returns error's message if ApiError or Error, else defaultMessage */ export const getErrorMessage = ( - error: unknown, - defaultMessage: string, + error: unknown, + defaultMessage: string, ): string => { - // if error is API error - // 404s result in the default message being returned - if (isApiError(error) && error.response.data.message) { - return error.response.data.message; - } - if (isApiErrorResponse(error)) { - return error.message; - } - // if error is a non-empty string - if (error && typeof error === "string") { - return error; - } - return defaultMessage; + // if error is API error + // 404s result in the default message being returned + if (isApiError(error) && error.response.data.message) { + return error.response.data.message; + } + if (isApiErrorResponse(error)) { + return error.message; + } + // if error is a non-empty string + if (error && typeof error === "string") { + return error; + } + return defaultMessage; }; /** @@ -103,38 +103,38 @@ export const getErrorMessage = ( * and contains validation messages for different form fields. */ export const getValidationErrorMessage = (error: unknown): string => { - const validationErrors = - isApiError(error) && error.response.data.validations - ? error.response.data.validations - : []; - return validationErrors.map((error) => error.detail).join("\n"); + const validationErrors = + isApiError(error) && error.response.data.validations + ? error.response.data.validations + : []; + return validationErrors.map((error) => error.detail).join("\n"); }; export const getErrorDetail = (error: unknown): string | undefined => { - if (error instanceof DetailedError) { - return error.detail; - } + if (error instanceof DetailedError) { + return error.detail; + } - if (error instanceof Error) { - return "Please check the developer console for more details."; - } + if (error instanceof Error) { + return "Please check the developer console for more details."; + } - if (isApiError(error)) { - return error.response.data.detail; - } + if (isApiError(error)) { + return error.response.data.detail; + } - if (isApiErrorResponse(error)) { - return error.detail; - } + if (isApiErrorResponse(error)) { + return error.detail; + } - return undefined; + return undefined; }; export class DetailedError extends Error { - constructor( - message: string, - public detail?: string, - ) { - super(message); - } + constructor( + message: string, + public detail?: string, + ) { + super(message); + } } diff --git a/site/src/api/queries/appearance.ts b/site/src/api/queries/appearance.ts index 4c10ad4da4..ddc248ccfa 100644 --- a/site/src/api/queries/appearance.ts +++ b/site/src/api/queries/appearance.ts @@ -7,18 +7,18 @@ import { cachedQuery } from "./util"; export const appearanceConfigKey = ["appearance"] as const; export const appearance = (metadata: MetadataState) => { - return cachedQuery({ - metadata, - queryKey: appearanceConfigKey, - queryFn: () => API.getAppearance(), - }); + return cachedQuery({ + metadata, + queryKey: appearanceConfigKey, + queryFn: () => API.getAppearance(), + }); }; export const updateAppearance = (queryClient: QueryClient) => { - return { - mutationFn: API.updateAppearance, - onSuccess: (newConfig: AppearanceConfig) => { - queryClient.setQueryData(appearanceConfigKey, newConfig); - }, - }; + return { + mutationFn: API.updateAppearance, + onSuccess: (newConfig: AppearanceConfig) => { + queryClient.setQueryData(appearanceConfigKey, newConfig); + }, + }; }; diff --git a/site/src/api/queries/audits.ts b/site/src/api/queries/audits.ts index 1dce9a29ea..224f8b0d12 100644 --- a/site/src/api/queries/audits.ts +++ b/site/src/api/queries/audits.ts @@ -4,21 +4,21 @@ import { useFilterParamsKey } from "components/Filter/filter"; import type { UsePaginatedQueryOptions } from "hooks/usePaginatedQuery"; export function paginatedAudits( - searchParams: URLSearchParams, + searchParams: URLSearchParams, ): UsePaginatedQueryOptions { - return { - searchParams, - queryPayload: () => searchParams.get(useFilterParamsKey) ?? "", - queryKey: ({ payload, pageNumber }) => { - return ["auditLogs", payload, pageNumber] as const; - }, - queryFn: ({ payload, limit, offset }) => { - return API.getAuditLogs({ - offset, - limit, - q: payload, - }); - }, - prefetch: false, - }; + return { + searchParams, + queryPayload: () => searchParams.get(useFilterParamsKey) ?? "", + queryKey: ({ payload, pageNumber }) => { + return ["auditLogs", payload, pageNumber] as const; + }, + queryFn: ({ payload, limit, offset }) => { + return API.getAuditLogs({ + offset, + limit, + q: payload, + }); + }, + prefetch: false, + }; } diff --git a/site/src/api/queries/authCheck.ts b/site/src/api/queries/authCheck.ts index 3248f35357..813bec8285 100644 --- a/site/src/api/queries/authCheck.ts +++ b/site/src/api/queries/authCheck.ts @@ -4,11 +4,11 @@ import type { AuthorizationRequest } from "api/typesGenerated"; export const AUTHORIZATION_KEY = "authorization"; export const getAuthorizationKey = (req: AuthorizationRequest) => - [AUTHORIZATION_KEY, req] as const; + [AUTHORIZATION_KEY, req] as const; export const checkAuthorization = (req: AuthorizationRequest) => { - return { - queryKey: getAuthorizationKey(req), - queryFn: () => API.checkAuthorization(req), - }; + return { + queryKey: getAuthorizationKey(req), + queryFn: () => API.checkAuthorization(req), + }; }; diff --git a/site/src/api/queries/buildInfo.ts b/site/src/api/queries/buildInfo.ts index 43dac7d203..1b2d9b118c 100644 --- a/site/src/api/queries/buildInfo.ts +++ b/site/src/api/queries/buildInfo.ts @@ -6,10 +6,10 @@ import { cachedQuery } from "./util"; const buildInfoKey = ["buildInfo"] as const; export const buildInfo = (metadata: MetadataState) => { - // The version of the app can't change without reloading the page. - return cachedQuery({ - metadata, - queryKey: buildInfoKey, - queryFn: () => API.getBuildInfo(), - }); + // The version of the app can't change without reloading the page. + return cachedQuery({ + metadata, + queryKey: buildInfoKey, + queryFn: () => API.getBuildInfo(), + }); }; diff --git a/site/src/api/queries/debug.ts b/site/src/api/queries/debug.ts index 42b43f7cc1..86dcb9a558 100644 --- a/site/src/api/queries/debug.ts +++ b/site/src/api/queries/debug.ts @@ -6,40 +6,40 @@ export const HEALTH_QUERY_KEY = ["health"]; export const HEALTH_QUERY_SETTINGS_KEY = ["health", "settings"]; export const health = () => ({ - queryKey: HEALTH_QUERY_KEY, - queryFn: async () => API.getHealth(), + queryKey: HEALTH_QUERY_KEY, + queryFn: async () => API.getHealth(), }); export const refreshHealth = (queryClient: QueryClient) => { - return { - mutationFn: async () => { - await queryClient.cancelQueries(HEALTH_QUERY_KEY); - const newHealthData = await API.getHealth(true); - queryClient.setQueryData(HEALTH_QUERY_KEY, newHealthData); - }, - }; + return { + mutationFn: async () => { + await queryClient.cancelQueries(HEALTH_QUERY_KEY); + const newHealthData = await API.getHealth(true); + queryClient.setQueryData(HEALTH_QUERY_KEY, newHealthData); + }, + }; }; export const healthSettings = () => { - return { - queryKey: HEALTH_QUERY_SETTINGS_KEY, - queryFn: API.getHealthSettings, - }; + return { + queryKey: HEALTH_QUERY_SETTINGS_KEY, + queryFn: API.getHealthSettings, + }; }; export const updateHealthSettings = ( - queryClient: QueryClient, + queryClient: QueryClient, ): UseMutationOptions< - HealthSettings, - unknown, - UpdateHealthSettings, - unknown + HealthSettings, + unknown, + UpdateHealthSettings, + unknown > => { - return { - mutationFn: API.updateHealthSettings, - onSuccess: async (_, newSettings) => { - await queryClient.invalidateQueries(HEALTH_QUERY_KEY); - queryClient.setQueryData(HEALTH_QUERY_SETTINGS_KEY, newSettings); - }, - }; + return { + mutationFn: API.updateHealthSettings, + onSuccess: async (_, newSettings) => { + await queryClient.invalidateQueries(HEALTH_QUERY_KEY); + queryClient.setQueryData(HEALTH_QUERY_SETTINGS_KEY, newSettings); + }, + }; }; diff --git a/site/src/api/queries/deployment.ts b/site/src/api/queries/deployment.ts index fa4d37967a..4ec1ba39b7 100644 --- a/site/src/api/queries/deployment.ts +++ b/site/src/api/queries/deployment.ts @@ -1,29 +1,29 @@ import { API } from "api/api"; export const deploymentConfig = () => { - return { - queryKey: ["deployment", "config"], - queryFn: API.getDeploymentConfig, - }; + return { + queryKey: ["deployment", "config"], + queryFn: API.getDeploymentConfig, + }; }; export const deploymentDAUs = () => { - return { - queryKey: ["deployment", "daus"], - queryFn: () => API.getDeploymentDAUs(), - }; + return { + queryKey: ["deployment", "daus"], + queryFn: () => API.getDeploymentDAUs(), + }; }; export const deploymentStats = () => { - return { - queryKey: ["deployment", "stats"], - queryFn: API.getDeploymentStats, - }; + return { + queryKey: ["deployment", "stats"], + queryFn: API.getDeploymentStats, + }; }; export const deploymentSSHConfig = () => { - return { - queryKey: ["deployment", "sshConfig"], - queryFn: API.getDeploymentSSHConfig, - }; + return { + queryKey: ["deployment", "sshConfig"], + queryFn: API.getDeploymentSSHConfig, + }; }; diff --git a/site/src/api/queries/entitlements.ts b/site/src/api/queries/entitlements.ts index 5d42a95767..cf06cf4af3 100644 --- a/site/src/api/queries/entitlements.ts +++ b/site/src/api/queries/entitlements.ts @@ -7,20 +7,20 @@ import { cachedQuery } from "./util"; const entitlementsQueryKey = ["entitlements"] as const; export const entitlements = (metadata: MetadataState) => { - return cachedQuery({ - metadata, - queryKey: entitlementsQueryKey, - queryFn: () => API.getEntitlements(), - }); + return cachedQuery({ + metadata, + queryKey: entitlementsQueryKey, + queryFn: () => API.getEntitlements(), + }); }; export const refreshEntitlements = (queryClient: QueryClient) => { - return { - mutationFn: API.refreshEntitlements, - onSuccess: async () => { - await queryClient.invalidateQueries({ - queryKey: entitlementsQueryKey, - }); - }, - }; + return { + mutationFn: API.refreshEntitlements, + onSuccess: async () => { + await queryClient.invalidateQueries({ + queryKey: entitlementsQueryKey, + }); + }, + }; }; diff --git a/site/src/api/queries/experiments.ts b/site/src/api/queries/experiments.ts index 86fd9096ae..546a85ab5f 100644 --- a/site/src/api/queries/experiments.ts +++ b/site/src/api/queries/experiments.ts @@ -6,16 +6,16 @@ import { cachedQuery } from "./util"; const experimentsKey = ["experiments"] as const; export const experiments = (metadata: MetadataState) => { - return cachedQuery({ - metadata, - queryKey: experimentsKey, - queryFn: () => API.getExperiments(), - }); + return cachedQuery({ + metadata, + queryKey: experimentsKey, + queryFn: () => API.getExperiments(), + }); }; export const availableExperiments = () => { - return { - queryKey: ["availableExperiments"], - queryFn: async () => API.getAvailableExperiments(), - }; + return { + queryKey: ["availableExperiments"], + queryFn: async () => API.getAvailableExperiments(), + }; }; diff --git a/site/src/api/queries/externalAuth.ts b/site/src/api/queries/externalAuth.ts index 3995940489..d02dad6b86 100644 --- a/site/src/api/queries/externalAuth.ts +++ b/site/src/api/queries/externalAuth.ts @@ -4,60 +4,60 @@ import type { QueryClient, UseMutationOptions } from "react-query"; // Returns all configured external auths for a given user. export const externalAuths = () => { - return { - queryKey: ["external-auth"], - queryFn: () => API.getUserExternalAuthProviders(), - }; + return { + queryKey: ["external-auth"], + queryFn: () => API.getUserExternalAuthProviders(), + }; }; export const externalAuthProvider = (providerId: string) => { - return { - queryKey: ["external-auth", providerId], - queryFn: () => API.getExternalAuthProvider(providerId), - }; + return { + queryKey: ["external-auth", providerId], + queryFn: () => API.getExternalAuthProvider(providerId), + }; }; export const externalAuthDevice = (providerId: string) => { - return { - queryFn: () => API.getExternalAuthDevice(providerId), - queryKey: ["external-auth", providerId, "device"], - }; + return { + queryFn: () => API.getExternalAuthDevice(providerId), + queryKey: ["external-auth", providerId, "device"], + }; }; export const exchangeExternalAuthDevice = ( - providerId: string, - deviceCode: string, - queryClient: QueryClient, + providerId: string, + deviceCode: string, + queryClient: QueryClient, ) => { - return { - queryFn: () => - API.exchangeExternalAuthDevice(providerId, { - device_code: deviceCode, - }), - queryKey: ["external-auth", providerId, "device", deviceCode], - onSuccess: async () => { - // Force a refresh of the Git auth status. - await queryClient.invalidateQueries(["external-auth", providerId]); - }, - }; + return { + queryFn: () => + API.exchangeExternalAuthDevice(providerId, { + device_code: deviceCode, + }), + queryKey: ["external-auth", providerId, "device", deviceCode], + onSuccess: async () => { + // Force a refresh of the Git auth status. + await queryClient.invalidateQueries(["external-auth", providerId]); + }, + }; }; export const validateExternalAuth = ( - queryClient: QueryClient, + queryClient: QueryClient, ): UseMutationOptions => { - return { - mutationFn: API.getExternalAuthProvider, - onSuccess: (data, providerId) => { - queryClient.setQueryData(["external-auth", providerId], data); - }, - }; + return { + mutationFn: API.getExternalAuthProvider, + onSuccess: (data, providerId) => { + queryClient.setQueryData(["external-auth", providerId], data); + }, + }; }; export const unlinkExternalAuths = (queryClient: QueryClient) => { - return { - mutationFn: API.unlinkExternalAuthProvider, - onSuccess: async () => { - await queryClient.invalidateQueries(["external-auth"]); - }, - }; + return { + mutationFn: API.unlinkExternalAuthProvider, + onSuccess: async () => { + await queryClient.invalidateQueries(["external-auth"]); + }, + }; }; diff --git a/site/src/api/queries/files.ts b/site/src/api/queries/files.ts index a363e03f94..0b1f107326 100644 --- a/site/src/api/queries/files.ts +++ b/site/src/api/queries/files.ts @@ -1,14 +1,14 @@ import { API } from "api/api"; export const uploadFile = () => { - return { - mutationFn: API.uploadFile, - }; + return { + mutationFn: API.uploadFile, + }; }; export const file = (fileId: string) => { - return { - queryKey: ["files", fileId], - queryFn: () => API.getFile(fileId), - }; + return { + queryKey: ["files", fileId], + queryFn: () => API.getFile(fileId), + }; }; diff --git a/site/src/api/queries/groups.ts b/site/src/api/queries/groups.ts index 72c612913c..e42ba57566 100644 --- a/site/src/api/queries/groups.ts +++ b/site/src/api/queries/groups.ts @@ -1,170 +1,170 @@ import { API } from "api/api"; import type { - CreateGroupRequest, - Group, - PatchGroupRequest, + CreateGroupRequest, + Group, + PatchGroupRequest, } from "api/typesGenerated"; import type { QueryClient, UseQueryOptions } from "react-query"; type GroupSortOrder = "asc" | "desc"; const getGroupsQueryKey = (organization: string) => [ - "organization", - organization, - "groups", + "organization", + organization, + "groups", ]; export const groups = (organization: string) => { - return { - queryKey: getGroupsQueryKey(organization), - queryFn: () => API.getGroups(organization), - } satisfies UseQueryOptions; + return { + queryKey: getGroupsQueryKey(organization), + queryFn: () => API.getGroups(organization), + } satisfies UseQueryOptions; }; const getGroupQueryKey = (organization: string, groupName: string) => [ - "organization", - organization, - "group", - groupName, + "organization", + organization, + "group", + groupName, ]; export const group = (organization: string, groupName: string) => { - return { - queryKey: getGroupQueryKey(organization, groupName), - queryFn: () => API.getGroup(organization, groupName), - }; + return { + queryKey: getGroupQueryKey(organization, groupName), + queryFn: () => API.getGroup(organization, groupName), + }; }; export type GroupsByUserId = Readonly>; export function groupsByUserId(organization: string) { - return { - ...groups(organization), - select: (allGroups) => { - // Sorting here means that nothing has to be sorted for the individual - // user arrays later - const sorted = sortGroupsByName(allGroups, "asc"); - const userIdMapper = new Map(); + return { + ...groups(organization), + select: (allGroups) => { + // Sorting here means that nothing has to be sorted for the individual + // user arrays later + const sorted = sortGroupsByName(allGroups, "asc"); + const userIdMapper = new Map(); - for (const group of sorted) { - for (const user of group.members) { - let groupsForUser = userIdMapper.get(user.id); - if (groupsForUser === undefined) { - groupsForUser = []; - userIdMapper.set(user.id, groupsForUser); - } + for (const group of sorted) { + for (const user of group.members) { + let groupsForUser = userIdMapper.get(user.id); + if (groupsForUser === undefined) { + groupsForUser = []; + userIdMapper.set(user.id, groupsForUser); + } - groupsForUser.push(group); - } - } + groupsForUser.push(group); + } + } - return userIdMapper as GroupsByUserId; - }, - } satisfies UseQueryOptions; + return userIdMapper as GroupsByUserId; + }, + } satisfies UseQueryOptions; } export function groupsForUser(organization: string, userId: string) { - return { - ...groups(organization), - select: (allGroups) => { - const groupsForUser = allGroups.filter((group) => { - const groupMemberIds = group.members.map((member) => member.id); - return groupMemberIds.includes(userId); - }); + return { + ...groups(organization), + select: (allGroups) => { + const groupsForUser = allGroups.filter((group) => { + const groupMemberIds = group.members.map((member) => member.id); + return groupMemberIds.includes(userId); + }); - return sortGroupsByName(groupsForUser, "asc"); - }, - } as const satisfies UseQueryOptions; + return sortGroupsByName(groupsForUser, "asc"); + }, + } as const satisfies UseQueryOptions; } export const groupPermissions = (groupId: string) => { - return { - queryKey: ["group", groupId, "permissions"], - queryFn: () => - API.checkAuthorization({ - checks: { - canUpdateGroup: { - object: { - resource_type: "group", - resource_id: groupId, - }, - action: "update", - }, - }, - }), - }; + return { + queryKey: ["group", groupId, "permissions"], + queryFn: () => + API.checkAuthorization({ + checks: { + canUpdateGroup: { + object: { + resource_type: "group", + resource_id: groupId, + }, + action: "update", + }, + }, + }), + }; }; export const createGroup = (queryClient: QueryClient, organization: string) => { - return { - mutationFn: (request: CreateGroupRequest) => - API.createGroup(organization, request), - onSuccess: async () => { - await queryClient.invalidateQueries(getGroupsQueryKey(organization)); - }, - }; + return { + mutationFn: (request: CreateGroupRequest) => + API.createGroup(organization, request), + onSuccess: async () => { + await queryClient.invalidateQueries(getGroupsQueryKey(organization)); + }, + }; }; export const patchGroup = (queryClient: QueryClient) => { - return { - mutationFn: ({ - groupId, - ...request - }: PatchGroupRequest & { groupId: string }) => - API.patchGroup(groupId, request), - onSuccess: async (updatedGroup: Group) => - invalidateGroup(queryClient, "default", updatedGroup.id), - }; + return { + mutationFn: ({ + groupId, + ...request + }: PatchGroupRequest & { groupId: string }) => + API.patchGroup(groupId, request), + onSuccess: async (updatedGroup: Group) => + invalidateGroup(queryClient, "default", updatedGroup.id), + }; }; export const deleteGroup = (queryClient: QueryClient) => { - return { - mutationFn: API.deleteGroup, - onSuccess: async (_: unknown, groupId: string) => - invalidateGroup(queryClient, "default", groupId), - }; + return { + mutationFn: API.deleteGroup, + onSuccess: async (_: unknown, groupId: string) => + invalidateGroup(queryClient, "default", groupId), + }; }; export const addMember = (queryClient: QueryClient) => { - return { - mutationFn: ({ groupId, userId }: { groupId: string; userId: string }) => - API.addMember(groupId, userId), - onSuccess: async (updatedGroup: Group) => - invalidateGroup(queryClient, "default", updatedGroup.id), - }; + return { + mutationFn: ({ groupId, userId }: { groupId: string; userId: string }) => + API.addMember(groupId, userId), + onSuccess: async (updatedGroup: Group) => + invalidateGroup(queryClient, "default", updatedGroup.id), + }; }; export const removeMember = (queryClient: QueryClient) => { - return { - mutationFn: ({ groupId, userId }: { groupId: string; userId: string }) => - API.removeMember(groupId, userId), - onSuccess: async (updatedGroup: Group) => - invalidateGroup(queryClient, "default", updatedGroup.id), - }; + return { + mutationFn: ({ groupId, userId }: { groupId: string; userId: string }) => + API.removeMember(groupId, userId), + onSuccess: async (updatedGroup: Group) => + invalidateGroup(queryClient, "default", updatedGroup.id), + }; }; export const invalidateGroup = ( - queryClient: QueryClient, - organization: string, - groupId: string, + queryClient: QueryClient, + organization: string, + groupId: string, ) => - Promise.all([ - queryClient.invalidateQueries(getGroupsQueryKey(organization)), - queryClient.invalidateQueries(getGroupQueryKey(organization, groupId)), - ]); + Promise.all([ + queryClient.invalidateQueries(getGroupsQueryKey(organization)), + queryClient.invalidateQueries(getGroupQueryKey(organization, groupId)), + ]); export function sortGroupsByName( - groups: readonly Group[], - order: GroupSortOrder, + groups: readonly Group[], + order: GroupSortOrder, ) { - return [...groups].sort((g1, g2) => { - const key = g1.display_name && g2.display_name ? "display_name" : "name"; - const direction = order === "asc" ? 1 : -1; + return [...groups].sort((g1, g2) => { + const key = g1.display_name && g2.display_name ? "display_name" : "name"; + const direction = order === "asc" ? 1 : -1; - if (g1[key] === g2[key]) { - return 0; - } + if (g1[key] === g2[key]) { + return 0; + } - return (g1[key] < g2[key] ? -1 : 1) * direction; - }); + return (g1[key] < g2[key] ? -1 : 1) * direction; + }); } diff --git a/site/src/api/queries/insights.ts b/site/src/api/queries/insights.ts index f179c11077..a7044a2f24 100644 --- a/site/src/api/queries/insights.ts +++ b/site/src/api/queries/insights.ts @@ -1,22 +1,22 @@ import { API, type InsightsParams, type InsightsTemplateParams } from "api/api"; export const insightsTemplate = (params: InsightsTemplateParams) => { - return { - queryKey: ["insights", "templates", params.template_ids, params], - queryFn: () => API.getInsightsTemplate(params), - }; + return { + queryKey: ["insights", "templates", params.template_ids, params], + queryFn: () => API.getInsightsTemplate(params), + }; }; export const insightsUserLatency = (params: InsightsParams) => { - return { - queryKey: ["insights", "userLatency", params.template_ids, params], - queryFn: () => API.getInsightsUserLatency(params), - }; + return { + queryKey: ["insights", "userLatency", params.template_ids, params], + queryFn: () => API.getInsightsUserLatency(params), + }; }; export const insightsUserActivity = (params: InsightsParams) => { - return { - queryKey: ["insights", "userActivity", params.template_ids, params], - queryFn: () => API.getInsightsUserActivity(params), - }; + return { + queryKey: ["insights", "userActivity", params.template_ids, params], + queryFn: () => API.getInsightsUserActivity(params), + }; }; diff --git a/site/src/api/queries/integrations.ts b/site/src/api/queries/integrations.ts index c0e7f6f28c..38b212da0e 100644 --- a/site/src/api/queries/integrations.ts +++ b/site/src/api/queries/integrations.ts @@ -2,8 +2,8 @@ import type { GetJFrogXRayScanParams } from "api/api"; import { API } from "api/api"; export const xrayScan = (params: GetJFrogXRayScanParams) => { - return { - queryKey: ["xray", params], - queryFn: () => API.getJFrogXRayScan(params), - }; + return { + queryKey: ["xray", params], + queryFn: () => API.getJFrogXRayScan(params), + }; }; diff --git a/site/src/api/queries/notifications.ts b/site/src/api/queries/notifications.ts index 9c784a036f..f8557637e7 100644 --- a/site/src/api/queries/notifications.ts +++ b/site/src/api/queries/notifications.ts @@ -1,138 +1,138 @@ import { API } from "api/api"; import type { - NotificationPreference, - NotificationTemplate, - UpdateNotificationTemplateMethod, - UpdateUserNotificationPreferences, + NotificationPreference, + NotificationTemplate, + UpdateNotificationTemplateMethod, + UpdateUserNotificationPreferences, } from "api/typesGenerated"; import type { QueryClient, UseMutationOptions } from "react-query"; export const userNotificationPreferencesKey = (userId: string) => [ - "users", - userId, - "notifications", - "preferences", + "users", + userId, + "notifications", + "preferences", ]; export const userNotificationPreferences = (userId: string) => { - return { - queryKey: userNotificationPreferencesKey(userId), - queryFn: () => API.getUserNotificationPreferences(userId), - }; + return { + queryKey: userNotificationPreferencesKey(userId), + queryFn: () => API.getUserNotificationPreferences(userId), + }; }; export const updateUserNotificationPreferences = ( - userId: string, - queryClient: QueryClient, + userId: string, + queryClient: QueryClient, ) => { - return { - mutationFn: (req) => { - return API.putUserNotificationPreferences(userId, req); - }, - onMutate: (data) => { - queryClient.setQueryData( - userNotificationPreferencesKey(userId), - Object.entries(data.template_disabled_map).map( - ([id, disabled]) => - ({ - id, - disabled, - updated_at: new Date().toISOString(), - }) satisfies NotificationPreference, - ), - ); - }, - } satisfies UseMutationOptions< - NotificationPreference[], - unknown, - UpdateUserNotificationPreferences - >; + return { + mutationFn: (req) => { + return API.putUserNotificationPreferences(userId, req); + }, + onMutate: (data) => { + queryClient.setQueryData( + userNotificationPreferencesKey(userId), + Object.entries(data.template_disabled_map).map( + ([id, disabled]) => + ({ + id, + disabled, + updated_at: new Date().toISOString(), + }) satisfies NotificationPreference, + ), + ); + }, + } satisfies UseMutationOptions< + NotificationPreference[], + unknown, + UpdateUserNotificationPreferences + >; }; export const systemNotificationTemplatesKey = [ - "notifications", - "templates", - "system", + "notifications", + "templates", + "system", ]; export const systemNotificationTemplates = () => { - return { - queryKey: systemNotificationTemplatesKey, - queryFn: () => API.getSystemNotificationTemplates(), - }; + return { + queryKey: systemNotificationTemplatesKey, + queryFn: () => API.getSystemNotificationTemplates(), + }; }; export function selectTemplatesByGroup( - data: NotificationTemplate[], + data: NotificationTemplate[], ): Record { - const grouped = data.reduce( - (acc, tpl) => { - if (!acc[tpl.group]) { - acc[tpl.group] = []; - } - acc[tpl.group].push(tpl); - return acc; - }, - {} as Record, - ); + const grouped = data.reduce( + (acc, tpl) => { + if (!acc[tpl.group]) { + acc[tpl.group] = []; + } + acc[tpl.group].push(tpl); + return acc; + }, + {} as Record, + ); - // Sort templates within each group - for (const group in grouped) { - grouped[group].sort((a, b) => a.name.localeCompare(b.name)); - } + // Sort templates within each group + for (const group in grouped) { + grouped[group].sort((a, b) => a.name.localeCompare(b.name)); + } - // Sort groups by name - const sortedGroups = Object.keys(grouped).sort((a, b) => a.localeCompare(b)); - const sortedGrouped: Record = {}; - for (const group of sortedGroups) { - sortedGrouped[group] = grouped[group]; - } + // Sort groups by name + const sortedGroups = Object.keys(grouped).sort((a, b) => a.localeCompare(b)); + const sortedGrouped: Record = {}; + for (const group of sortedGroups) { + sortedGrouped[group] = grouped[group]; + } - return sortedGrouped; + return sortedGrouped; } export const notificationDispatchMethodsKey = [ - "notifications", - "dispatchMethods", + "notifications", + "dispatchMethods", ]; export const notificationDispatchMethods = () => { - return { - staleTime: Number.POSITIVE_INFINITY, - queryKey: notificationDispatchMethodsKey, - queryFn: () => API.getNotificationDispatchMethods(), - }; + return { + staleTime: Number.POSITIVE_INFINITY, + queryKey: notificationDispatchMethodsKey, + queryFn: () => API.getNotificationDispatchMethods(), + }; }; export const updateNotificationTemplateMethod = ( - templateId: string, - queryClient: QueryClient, + templateId: string, + queryClient: QueryClient, ) => { - return { - mutationFn: (req: UpdateNotificationTemplateMethod) => - API.updateNotificationTemplateMethod(templateId, req), - onMutate: (data) => { - const prevData = queryClient.getQueryData( - systemNotificationTemplatesKey, - ); - if (!prevData) { - return; - } - queryClient.setQueryData( - systemNotificationTemplatesKey, - prevData.map((tpl) => - tpl.id === templateId - ? { - ...tpl, - method: data.method, - } - : tpl, - ), - ); - }, - } satisfies UseMutationOptions< - void, - unknown, - UpdateNotificationTemplateMethod - >; + return { + mutationFn: (req: UpdateNotificationTemplateMethod) => + API.updateNotificationTemplateMethod(templateId, req), + onMutate: (data) => { + const prevData = queryClient.getQueryData( + systemNotificationTemplatesKey, + ); + if (!prevData) { + return; + } + queryClient.setQueryData( + systemNotificationTemplatesKey, + prevData.map((tpl) => + tpl.id === templateId + ? { + ...tpl, + method: data.method, + } + : tpl, + ), + ); + }, + } satisfies UseMutationOptions< + void, + unknown, + UpdateNotificationTemplateMethod + >; }; diff --git a/site/src/api/queries/oauth2.ts b/site/src/api/queries/oauth2.ts index d52a8c56b6..66547418c8 100644 --- a/site/src/api/queries/oauth2.ts +++ b/site/src/api/queries/oauth2.ts @@ -8,98 +8,98 @@ const appKey = (appId: string) => appsKey.concat(appId); const appSecretsKey = (appId: string) => appKey(appId).concat("secrets"); export const getApps = (userId?: string) => { - return { - queryKey: userId ? appsKey.concat(userId) : appsKey, - queryFn: () => API.getOAuth2ProviderApps({ user_id: userId }), - }; + return { + queryKey: userId ? appsKey.concat(userId) : appsKey, + queryFn: () => API.getOAuth2ProviderApps({ user_id: userId }), + }; }; export const getApp = (id: string) => { - return { - queryKey: appKey(id), - queryFn: () => API.getOAuth2ProviderApp(id), - }; + return { + queryKey: appKey(id), + queryFn: () => API.getOAuth2ProviderApp(id), + }; }; export const postApp = (queryClient: QueryClient) => { - return { - mutationFn: API.postOAuth2ProviderApp, - onSuccess: async () => { - await queryClient.invalidateQueries({ - queryKey: appsKey, - }); - }, - }; + return { + mutationFn: API.postOAuth2ProviderApp, + onSuccess: async () => { + await queryClient.invalidateQueries({ + queryKey: appsKey, + }); + }, + }; }; export const putApp = (queryClient: QueryClient) => { - return { - mutationFn: ({ - id, - req, - }: { - id: string; - req: TypesGen.PutOAuth2ProviderAppRequest; - }) => API.putOAuth2ProviderApp(id, req), - onSuccess: async (app: TypesGen.OAuth2ProviderApp) => { - await queryClient.invalidateQueries({ - queryKey: appKey(app.id), - }); - }, - }; + return { + mutationFn: ({ + id, + req, + }: { + id: string; + req: TypesGen.PutOAuth2ProviderAppRequest; + }) => API.putOAuth2ProviderApp(id, req), + onSuccess: async (app: TypesGen.OAuth2ProviderApp) => { + await queryClient.invalidateQueries({ + queryKey: appKey(app.id), + }); + }, + }; }; export const deleteApp = (queryClient: QueryClient) => { - return { - mutationFn: API.deleteOAuth2ProviderApp, - onSuccess: async () => { - await queryClient.invalidateQueries({ - queryKey: appsKey, - }); - }, - }; + return { + mutationFn: API.deleteOAuth2ProviderApp, + onSuccess: async () => { + await queryClient.invalidateQueries({ + queryKey: appsKey, + }); + }, + }; }; export const getAppSecrets = (id: string) => { - return { - queryKey: appSecretsKey(id), - queryFn: () => API.getOAuth2ProviderAppSecrets(id), - }; + return { + queryKey: appSecretsKey(id), + queryFn: () => API.getOAuth2ProviderAppSecrets(id), + }; }; export const postAppSecret = (queryClient: QueryClient) => { - return { - mutationFn: API.postOAuth2ProviderAppSecret, - onSuccess: async ( - _: TypesGen.OAuth2ProviderAppSecretFull, - appId: string, - ) => { - await queryClient.invalidateQueries({ - queryKey: appSecretsKey(appId), - }); - }, - }; + return { + mutationFn: API.postOAuth2ProviderAppSecret, + onSuccess: async ( + _: TypesGen.OAuth2ProviderAppSecretFull, + appId: string, + ) => { + await queryClient.invalidateQueries({ + queryKey: appSecretsKey(appId), + }); + }, + }; }; export const deleteAppSecret = (queryClient: QueryClient) => { - return { - mutationFn: ({ appId, secretId }: { appId: string; secretId: string }) => - API.deleteOAuth2ProviderAppSecret(appId, secretId), - onSuccess: async (_: unknown, { appId }: { appId: string }) => { - await queryClient.invalidateQueries({ - queryKey: appSecretsKey(appId), - }); - }, - }; + return { + mutationFn: ({ appId, secretId }: { appId: string; secretId: string }) => + API.deleteOAuth2ProviderAppSecret(appId, secretId), + onSuccess: async (_: unknown, { appId }: { appId: string }) => { + await queryClient.invalidateQueries({ + queryKey: appSecretsKey(appId), + }); + }, + }; }; export const revokeApp = (queryClient: QueryClient, userId: string) => { - return { - mutationFn: API.revokeOAuth2ProviderApp, - onSuccess: async () => { - await queryClient.invalidateQueries({ - queryKey: userAppsKey(userId), - }); - }, - }; + return { + mutationFn: API.revokeOAuth2ProviderApp, + onSuccess: async () => { + await queryClient.invalidateQueries({ + queryKey: userAppsKey(userId), + }); + }, + }; }; diff --git a/site/src/api/queries/organizations.ts b/site/src/api/queries/organizations.ts index 41a2fbaf9b..54ff0ca883 100644 --- a/site/src/api/queries/organizations.ts +++ b/site/src/api/queries/organizations.ts @@ -1,125 +1,125 @@ import { API } from "api/api"; import type { - AuthorizationResponse, - CreateOrganizationRequest, - UpdateOrganizationRequest, + AuthorizationResponse, + CreateOrganizationRequest, + UpdateOrganizationRequest, } from "api/typesGenerated"; import type { QueryClient } from "react-query"; import { meKey } from "./users"; export const createOrganization = (queryClient: QueryClient) => { - return { - mutationFn: (params: CreateOrganizationRequest) => - API.createOrganization(params), + return { + mutationFn: (params: CreateOrganizationRequest) => + API.createOrganization(params), - onSuccess: async () => { - await queryClient.invalidateQueries(meKey); - await queryClient.invalidateQueries(organizationsKey); - }, - }; + onSuccess: async () => { + await queryClient.invalidateQueries(meKey); + await queryClient.invalidateQueries(organizationsKey); + }, + }; }; interface UpdateOrganizationVariables { - organizationId: string; - req: UpdateOrganizationRequest; + organizationId: string; + req: UpdateOrganizationRequest; } export const updateOrganization = (queryClient: QueryClient) => { - return { - mutationFn: (variables: UpdateOrganizationVariables) => - API.updateOrganization(variables.organizationId, variables.req), + return { + mutationFn: (variables: UpdateOrganizationVariables) => + API.updateOrganization(variables.organizationId, variables.req), - onSuccess: async () => { - await queryClient.invalidateQueries(organizationsKey); - }, - }; + onSuccess: async () => { + await queryClient.invalidateQueries(organizationsKey); + }, + }; }; export const deleteOrganization = (queryClient: QueryClient) => { - return { - mutationFn: (organizationId: string) => - API.deleteOrganization(organizationId), + return { + mutationFn: (organizationId: string) => + API.deleteOrganization(organizationId), - onSuccess: async () => { - await queryClient.invalidateQueries(meKey); - await queryClient.invalidateQueries(organizationsKey); - }, - }; + onSuccess: async () => { + await queryClient.invalidateQueries(meKey); + await queryClient.invalidateQueries(organizationsKey); + }, + }; }; export const organizationMembers = (id: string) => { - return { - queryFn: () => API.getOrganizationMembers(id), - queryKey: ["organization", id, "members"], - }; + return { + queryFn: () => API.getOrganizationMembers(id), + queryKey: ["organization", id, "members"], + }; }; export const addOrganizationMember = (queryClient: QueryClient, id: string) => { - return { - mutationFn: (userId: string) => { - return API.addOrganizationMember(id, userId); - }, + return { + mutationFn: (userId: string) => { + return API.addOrganizationMember(id, userId); + }, - onSuccess: async () => { - await queryClient.invalidateQueries(["organization", id, "members"]); - }, - }; + onSuccess: async () => { + await queryClient.invalidateQueries(["organization", id, "members"]); + }, + }; }; export const removeOrganizationMember = ( - queryClient: QueryClient, - id: string, + queryClient: QueryClient, + id: string, ) => { - return { - mutationFn: (userId: string) => { - return API.removeOrganizationMember(id, userId); - }, + return { + mutationFn: (userId: string) => { + return API.removeOrganizationMember(id, userId); + }, - onSuccess: async () => { - await queryClient.invalidateQueries(["organization", id, "members"]); - }, - }; + onSuccess: async () => { + await queryClient.invalidateQueries(["organization", id, "members"]); + }, + }; }; export const updateOrganizationMemberRoles = ( - queryClient: QueryClient, - organizationId: string, + queryClient: QueryClient, + organizationId: string, ) => { - return { - mutationFn: ({ userId, roles }: { userId: string; roles: string[] }) => { - return API.updateOrganizationMemberRoles(organizationId, userId, roles); - }, + return { + mutationFn: ({ userId, roles }: { userId: string; roles: string[] }) => { + return API.updateOrganizationMemberRoles(organizationId, userId, roles); + }, - onSuccess: async () => { - await queryClient.invalidateQueries([ - "organization", - organizationId, - "members", - ]); - }, - }; + onSuccess: async () => { + await queryClient.invalidateQueries([ + "organization", + organizationId, + "members", + ]); + }, + }; }; export const organizationsKey = ["organizations"] as const; export const organizations = () => { - return { - queryKey: organizationsKey, - queryFn: () => API.getOrganizations(), - }; + return { + queryKey: organizationsKey, + queryFn: () => API.getOrganizations(), + }; }; export const getProvisionerDaemonsKey = (organization: string) => [ - "organization", - organization, - "provisionerDaemons", + "organization", + organization, + "provisionerDaemons", ]; export const provisionerDaemons = (organization: string) => { - return { - queryKey: getProvisionerDaemonsKey(organization), - queryFn: () => API.getProvisionerDaemonsByOrganization(organization), - }; + return { + queryKey: getProvisionerDaemonsKey(organization), + queryFn: () => API.getProvisionerDaemonsByOrganization(organization), + }; }; /** @@ -128,45 +128,45 @@ export const provisionerDaemons = (organization: string) => { * If the ID is undefined, return a disabled query. */ export const organizationPermissions = (organizationId: string | undefined) => { - if (!organizationId) { - return { enabled: false }; - } - return { - queryKey: ["organization", organizationId, "permissions"], - queryFn: () => - // Only request what we use on individual org settings, members, and group - // pages, which at the moment is whether you can edit the members on the - // members page, create roles on the roles page, and create groups on the - // groups page. The edit organization check for the settings page is - // covered by the multi-org query at the moment, and the edit group check - // on the group page is done on the group itself, not the org, so neither - // show up here. - API.checkAuthorization({ - checks: { - editMembers: { - object: { - resource_type: "organization_member", - organization_id: organizationId, - }, - action: "update", - }, - createGroup: { - object: { - resource_type: "group", - organization_id: organizationId, - }, - action: "create", - }, - assignOrgRole: { - object: { - resource_type: "assign_org_role", - organization_id: organizationId, - }, - action: "create", - }, - }, - }), - }; + if (!organizationId) { + return { enabled: false }; + } + return { + queryKey: ["organization", organizationId, "permissions"], + queryFn: () => + // Only request what we use on individual org settings, members, and group + // pages, which at the moment is whether you can edit the members on the + // members page, create roles on the roles page, and create groups on the + // groups page. The edit organization check for the settings page is + // covered by the multi-org query at the moment, and the edit group check + // on the group page is done on the group itself, not the org, so neither + // show up here. + API.checkAuthorization({ + checks: { + editMembers: { + object: { + resource_type: "organization_member", + organization_id: organizationId, + }, + action: "update", + }, + createGroup: { + object: { + resource_type: "group", + organization_id: organizationId, + }, + action: "create", + }, + assignOrgRole: { + object: { + resource_type: "assign_org_role", + organization_id: organizationId, + }, + action: "create", + }, + }, + }), + }; }; /** @@ -175,77 +175,77 @@ export const organizationPermissions = (organizationId: string | undefined) => { * If organizations are undefined, return a disabled query. */ export const organizationsPermissions = ( - organizationIds: string[] | undefined, + organizationIds: string[] | undefined, ) => { - if (!organizationIds) { - return { enabled: false }; - } + if (!organizationIds) { + return { enabled: false }; + } - return { - queryKey: ["organizations", organizationIds.sort(), "permissions"], - queryFn: async () => { - // Only request what we need for the sidebar, which is one edit permission - // per sub-link (settings, groups, roles, and members pages) that tells us - // whether to show that page, since we only show them if you can edit (and - // not, at the moment if you can only view). - const checks = (organizationId: string) => ({ - editMembers: { - object: { - resource_type: "organization_member", - organization_id: organizationId, - }, - action: "update", - }, - editGroups: { - object: { - resource_type: "group", - organization_id: organizationId, - }, - action: "update", - }, - editOrganization: { - object: { - resource_type: "organization", - organization_id: organizationId, - }, - action: "update", - }, - assignOrgRole: { - object: { - resource_type: "assign_org_role", - organization_id: organizationId, - }, - action: "create", - }, - }); + return { + queryKey: ["organizations", organizationIds.sort(), "permissions"], + queryFn: async () => { + // Only request what we need for the sidebar, which is one edit permission + // per sub-link (settings, groups, roles, and members pages) that tells us + // whether to show that page, since we only show them if you can edit (and + // not, at the moment if you can only view). + const checks = (organizationId: string) => ({ + editMembers: { + object: { + resource_type: "organization_member", + organization_id: organizationId, + }, + action: "update", + }, + editGroups: { + object: { + resource_type: "group", + organization_id: organizationId, + }, + action: "update", + }, + editOrganization: { + object: { + resource_type: "organization", + organization_id: organizationId, + }, + action: "update", + }, + assignOrgRole: { + object: { + resource_type: "assign_org_role", + organization_id: organizationId, + }, + action: "create", + }, + }); - // The endpoint takes a flat array, so to avoid collisions prepend each - // check with the org ID (the key can be anything we want). - const prefixedChecks = organizationIds.flatMap((orgId) => - Object.entries(checks(orgId)).map(([key, val]) => [ - `${orgId}.${key}`, - val, - ]), - ); + // The endpoint takes a flat array, so to avoid collisions prepend each + // check with the org ID (the key can be anything we want). + const prefixedChecks = organizationIds.flatMap((orgId) => + Object.entries(checks(orgId)).map(([key, val]) => [ + `${orgId}.${key}`, + val, + ]), + ); - const response = await API.checkAuthorization({ - checks: Object.fromEntries(prefixedChecks), - }); + const response = await API.checkAuthorization({ + checks: Object.fromEntries(prefixedChecks), + }); - // Now we can unflatten by parsing out the org ID from each check. - return Object.entries(response).reduce( - (acc, [key, value]) => { - const index = key.indexOf("."); - const orgId = key.substring(0, index); - const perm = key.substring(index + 1); - if (!acc[orgId]) { - acc[orgId] = {}; - } - acc[orgId][perm] = value; - return acc; - }, - {} as Record, - ); - }, - }; + // Now we can unflatten by parsing out the org ID from each check. + return Object.entries(response).reduce( + (acc, [key, value]) => { + const index = key.indexOf("."); + const orgId = key.substring(0, index); + const perm = key.substring(index + 1); + if (!acc[orgId]) { + acc[orgId] = {}; + } + acc[orgId][perm] = value; + return acc; + }, + {} as Record, + ); + }, + }; }; diff --git a/site/src/api/queries/roles.ts b/site/src/api/queries/roles.ts index 5982e1cdc5..97e5e29eea 100644 --- a/site/src/api/queries/roles.ts +++ b/site/src/api/queries/roles.ts @@ -3,64 +3,64 @@ import type { Role } from "api/typesGenerated"; import type { QueryClient } from "react-query"; const getRoleQueryKey = (organizationId: string, roleName: string) => [ - "organization", - organizationId, - "role", - roleName, + "organization", + organizationId, + "role", + roleName, ]; export const roles = () => { - return { - queryKey: ["roles"], - queryFn: API.getRoles, - }; + return { + queryKey: ["roles"], + queryFn: API.getRoles, + }; }; export const organizationRoles = (organization: string) => { - return { - queryKey: ["organization", organization, "roles"], - queryFn: () => API.getOrganizationRoles(organization), - }; + return { + queryKey: ["organization", organization, "roles"], + queryFn: () => API.getOrganizationRoles(organization), + }; }; export const createOrganizationRole = ( - queryClient: QueryClient, - organization: string, + queryClient: QueryClient, + organization: string, ) => { - return { - mutationFn: (request: Role) => - API.createOrganizationRole(organization, request), - onSuccess: async (updatedRole: Role) => - await queryClient.invalidateQueries( - getRoleQueryKey(organization, updatedRole.name), - ), - }; + return { + mutationFn: (request: Role) => + API.createOrganizationRole(organization, request), + onSuccess: async (updatedRole: Role) => + await queryClient.invalidateQueries( + getRoleQueryKey(organization, updatedRole.name), + ), + }; }; export const updateOrganizationRole = ( - queryClient: QueryClient, - organization: string, + queryClient: QueryClient, + organization: string, ) => { - return { - mutationFn: (request: Role) => - API.updateOrganizationRole(organization, request), - onSuccess: async (updatedRole: Role) => - await queryClient.invalidateQueries( - getRoleQueryKey(organization, updatedRole.name), - ), - }; + return { + mutationFn: (request: Role) => + API.updateOrganizationRole(organization, request), + onSuccess: async (updatedRole: Role) => + await queryClient.invalidateQueries( + getRoleQueryKey(organization, updatedRole.name), + ), + }; }; export const deleteOrganizationRole = ( - queryClient: QueryClient, - organization: string, + queryClient: QueryClient, + organization: string, ) => { - return { - mutationFn: (roleName: string) => - API.deleteOrganizationRole(organization, roleName), - onSuccess: async (_: unknown, roleName: string) => - await queryClient.invalidateQueries( - getRoleQueryKey(organization, roleName), - ), - }; + return { + mutationFn: (roleName: string) => + API.deleteOrganizationRole(organization, roleName), + onSuccess: async (_: unknown, roleName: string) => + await queryClient.invalidateQueries( + getRoleQueryKey(organization, roleName), + ), + }; }; diff --git a/site/src/api/queries/settings.ts b/site/src/api/queries/settings.ts index 4dbce97d44..5b040508ae 100644 --- a/site/src/api/queries/settings.ts +++ b/site/src/api/queries/settings.ts @@ -1,34 +1,34 @@ import { API } from "api/api"; import type { - UpdateUserQuietHoursScheduleRequest, - UserQuietHoursScheduleResponse, + UpdateUserQuietHoursScheduleRequest, + UserQuietHoursScheduleResponse, } from "api/typesGenerated"; import type { QueryClient, QueryOptions } from "react-query"; export const userQuietHoursScheduleKey = (userId: string) => [ - "settings", - userId, - "quietHours", + "settings", + userId, + "quietHours", ]; export const userQuietHoursSchedule = ( - userId: string, + userId: string, ): QueryOptions => { - return { - queryKey: userQuietHoursScheduleKey(userId), - queryFn: () => API.getUserQuietHoursSchedule(userId), - }; + return { + queryKey: userQuietHoursScheduleKey(userId), + queryFn: () => API.getUserQuietHoursSchedule(userId), + }; }; export const updateUserQuietHoursSchedule = ( - userId: string, - queryClient: QueryClient, + userId: string, + queryClient: QueryClient, ) => { - return { - mutationFn: (request: UpdateUserQuietHoursScheduleRequest) => - API.updateUserQuietHoursSchedule(userId, request), - onSuccess: async () => { - await queryClient.invalidateQueries(userQuietHoursScheduleKey(userId)); - }, - }; + return { + mutationFn: (request: UpdateUserQuietHoursScheduleRequest) => + API.updateUserQuietHoursSchedule(userId, request), + onSuccess: async () => { + await queryClient.invalidateQueries(userQuietHoursScheduleKey(userId)); + }, + }; }; diff --git a/site/src/api/queries/sshKeys.ts b/site/src/api/queries/sshKeys.ts index 5173a7aa2e..f782756c7b 100644 --- a/site/src/api/queries/sshKeys.ts +++ b/site/src/api/queries/sshKeys.ts @@ -5,20 +5,20 @@ import type { QueryClient } from "react-query"; const getUserSSHKeyQueryKey = (userId: string) => [userId, "sshKey"]; export const userSSHKey = (userId: string) => { - return { - queryKey: getUserSSHKeyQueryKey(userId), - queryFn: () => API.getUserSSHKey(userId), - }; + return { + queryKey: getUserSSHKeyQueryKey(userId), + queryFn: () => API.getUserSSHKey(userId), + }; }; export const regenerateUserSSHKey = ( - userId: string, - queryClient: QueryClient, + userId: string, + queryClient: QueryClient, ) => { - return { - mutationFn: () => API.regenerateUserSSHKey(userId), - onSuccess: (newKey: GitSSHKey) => { - queryClient.setQueryData(getUserSSHKeyQueryKey(userId), newKey); - }, - }; + return { + mutationFn: () => API.regenerateUserSSHKey(userId), + onSuccess: (newKey: GitSSHKey) => { + queryClient.setQueryData(getUserSSHKeyQueryKey(userId), newKey); + }, + }; }; diff --git a/site/src/api/queries/templates.ts b/site/src/api/queries/templates.ts index 0012f4394b..8f6399cc4b 100644 --- a/site/src/api/queries/templates.ts +++ b/site/src/api/queries/templates.ts @@ -1,13 +1,13 @@ import { API, type GetTemplatesOptions, type GetTemplatesQuery } from "api/api"; import type { - CreateTemplateRequest, - CreateTemplateVersionRequest, - ProvisionerJob, - ProvisionerJobStatus, - Template, - TemplateRole, - TemplateVersion, - UsersRequest, + CreateTemplateRequest, + CreateTemplateVersionRequest, + ProvisionerJob, + ProvisionerJobStatus, + Template, + TemplateRole, + TemplateVersion, + UsersRequest, } from "api/typesGenerated"; import type { MutationOptions, QueryClient, QueryOptions } from "react-query"; import { delay } from "utils/delay"; @@ -16,324 +16,324 @@ import { getTemplateVersionFiles } from "utils/templateVersion"; export const templateKey = (templateId: string) => ["template", templateId]; export const template = (templateId: string): QueryOptions