Skip to content

Commit 28e1156

Browse files
committed
Merge remote-tracking branch 'origin/main' into stevenmasley/merge_oidc_account
2 parents 949e687 + 7072b8e commit 28e1156

25 files changed

+294
-59
lines changed

cli/testdata/coder_server_--help.golden

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ Use a YAML configuration file when your server launch become unwieldy.
7474
Write out the current server config as YAML to stdout.
7575

7676
Introspection / Logging Options
77+
--enable-terraform-debug-mode bool, $CODER_ENABLE_TERRAFORM_DEBUG_MODE (default: false)
78+
Allow administrators to enable Terraform debug output.
79+
7780
--log-human string, $CODER_LOGGING_HUMAN (default: /dev/stderr)
7881
Output human-readable logs to a given file.
7982

cli/testdata/server-config.yaml.golden

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,9 @@ introspection:
201201
# Output Stackdriver compatible logs to a given file.
202202
# (default: <unset>, type: string)
203203
stackdriverPath: ""
204+
# Allow administrators to enable Terraform debug output.
205+
# (default: false, type: bool)
206+
enableTerraformDebugMode: false
204207
oauth2:
205208
github:
206209
# Client ID for Login with GitHub.

coderd/apidoc/docs.go

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/apidoc/swagger.json

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/workspacebuilds.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,8 @@ func (api *API) postWorkspaceBuilds(rw http.ResponseWriter, r *http.Request) {
316316
builder := wsbuilder.New(workspace, database.WorkspaceTransition(createBuild.Transition)).
317317
Initiator(apiKey.UserID).
318318
RichParameterValues(createBuild.RichParameterValues).
319-
LogLevel(string(createBuild.LogLevel))
319+
LogLevel(string(createBuild.LogLevel)).
320+
DeploymentValues(api.Options.DeploymentValues)
320321

321322
if createBuild.TemplateVersionID != uuid.Nil {
322323
builder = builder.VersionID(createBuild.TemplateVersionID)

coderd/workspacebuilds_test.go

Lines changed: 90 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -640,11 +640,50 @@ func TestWorkspaceBuildStatus(t *testing.T) {
640640
func TestWorkspaceBuildDebugMode(t *testing.T) {
641641
t.Parallel()
642642

643+
t.Run("DebugModeDisabled", func(t *testing.T) {
644+
t.Parallel()
645+
646+
// Create user
647+
deploymentValues := coderdtest.DeploymentValues(t)
648+
deploymentValues.EnableTerraformDebugMode = false
649+
650+
adminClient := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true, DeploymentValues: deploymentValues})
651+
owner := coderdtest.CreateFirstUser(t, adminClient)
652+
653+
// Template author: create a template
654+
version := coderdtest.CreateTemplateVersion(t, adminClient, owner.OrganizationID, nil)
655+
template := coderdtest.CreateTemplate(t, adminClient, owner.OrganizationID, version.ID)
656+
coderdtest.AwaitTemplateVersionJob(t, adminClient, version.ID)
657+
658+
// Template author: create a workspace
659+
workspace := coderdtest.CreateWorkspace(t, adminClient, owner.OrganizationID, template.ID)
660+
coderdtest.AwaitWorkspaceBuildJob(t, adminClient, workspace.LatestBuild.ID)
661+
662+
// Template author: try to start a workspace build in debug mode
663+
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
664+
defer cancel()
665+
666+
_, err := adminClient.CreateWorkspaceBuild(ctx, workspace.ID, codersdk.CreateWorkspaceBuildRequest{
667+
TemplateVersionID: workspace.LatestBuild.TemplateVersionID,
668+
Transition: codersdk.WorkspaceTransitionStart,
669+
LogLevel: "debug",
670+
})
671+
672+
// Template author: expect an error as the debug mode is disabled
673+
require.NotNil(t, err)
674+
var sdkError *codersdk.Error
675+
isSdkError := xerrors.As(err, &sdkError)
676+
require.True(t, isSdkError)
677+
require.Contains(t, sdkError.Message, "Terraform debug mode is disabled in the deployment configuration.")
678+
})
643679
t.Run("AsRegularUser", func(t *testing.T) {
644680
t.Parallel()
645681

646682
// Create users
647-
templateAuthorClient := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
683+
deploymentValues := coderdtest.DeploymentValues(t)
684+
deploymentValues.EnableTerraformDebugMode = true
685+
686+
templateAuthorClient := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true, DeploymentValues: deploymentValues})
648687
templateAuthor := coderdtest.CreateFirstUser(t, templateAuthorClient)
649688
regularUserClient, _ := coderdtest.CreateAnotherUser(t, templateAuthorClient, templateAuthor.OrganizationID)
650689

@@ -672,15 +711,54 @@ func TestWorkspaceBuildDebugMode(t *testing.T) {
672711
var sdkError *codersdk.Error
673712
isSdkError := xerrors.As(err, &sdkError)
674713
require.True(t, isSdkError)
675-
require.Contains(t, sdkError.Message, "Workspace builds with a custom log level are restricted to template authors only.")
714+
require.Contains(t, sdkError.Message, "Workspace builds with a custom log level are restricted to administrators only.")
676715
})
677716
t.Run("AsTemplateAuthor", func(t *testing.T) {
678717
t.Parallel()
679718

680719
// Create users
681-
adminClient := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
720+
deploymentValues := coderdtest.DeploymentValues(t)
721+
deploymentValues.EnableTerraformDebugMode = true
722+
723+
adminClient := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true, DeploymentValues: deploymentValues})
724+
admin := coderdtest.CreateFirstUser(t, adminClient)
725+
templateAuthorClient, _ := coderdtest.CreateAnotherUser(t, adminClient, admin.OrganizationID, rbac.RoleTemplateAdmin())
726+
727+
// Template author: create a template
728+
version := coderdtest.CreateTemplateVersion(t, templateAuthorClient, admin.OrganizationID, nil)
729+
template := coderdtest.CreateTemplate(t, templateAuthorClient, admin.OrganizationID, version.ID)
730+
coderdtest.AwaitTemplateVersionJob(t, templateAuthorClient, version.ID)
731+
732+
// Template author: create a workspace
733+
workspace := coderdtest.CreateWorkspace(t, templateAuthorClient, admin.OrganizationID, template.ID)
734+
coderdtest.AwaitWorkspaceBuildJob(t, templateAuthorClient, workspace.LatestBuild.ID)
735+
736+
// Template author: try to start a workspace build in debug mode
737+
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
738+
defer cancel()
739+
740+
_, err := templateAuthorClient.CreateWorkspaceBuild(ctx, workspace.ID, codersdk.CreateWorkspaceBuildRequest{
741+
TemplateVersionID: workspace.LatestBuild.TemplateVersionID,
742+
Transition: codersdk.WorkspaceTransitionStart,
743+
LogLevel: "debug",
744+
})
745+
746+
// Template author: expect an error as the debug mode is disabled
747+
require.NotNil(t, err)
748+
var sdkError *codersdk.Error
749+
isSdkError := xerrors.As(err, &sdkError)
750+
require.True(t, isSdkError)
751+
require.Contains(t, sdkError.Message, "Workspace builds with a custom log level are restricted to administrators only.")
752+
})
753+
t.Run("AsAdmin", func(t *testing.T) {
754+
t.Parallel()
755+
756+
// Create users
757+
deploymentValues := coderdtest.DeploymentValues(t)
758+
deploymentValues.EnableTerraformDebugMode = true
759+
760+
adminClient := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true, DeploymentValues: deploymentValues})
682761
admin := coderdtest.CreateFirstUser(t, adminClient)
683-
templateAdminClient, _ := coderdtest.CreateAnotherUser(t, adminClient, admin.OrganizationID, rbac.RoleTemplateAdmin())
684762

685763
// Interact as template admin
686764
echoResponses := &echo.Responses{
@@ -713,30 +791,30 @@ func TestWorkspaceBuildDebugMode(t *testing.T) {
713791
},
714792
}},
715793
}
716-
version := coderdtest.CreateTemplateVersion(t, templateAdminClient, admin.OrganizationID, echoResponses)
717-
template := coderdtest.CreateTemplate(t, templateAdminClient, admin.OrganizationID, version.ID)
718-
coderdtest.AwaitTemplateVersionJob(t, templateAdminClient, version.ID)
794+
version := coderdtest.CreateTemplateVersion(t, adminClient, admin.OrganizationID, echoResponses)
795+
template := coderdtest.CreateTemplate(t, adminClient, admin.OrganizationID, version.ID)
796+
coderdtest.AwaitTemplateVersionJob(t, adminClient, version.ID)
719797

720798
// Create workspace
721-
workspace := coderdtest.CreateWorkspace(t, templateAdminClient, admin.OrganizationID, template.ID)
722-
coderdtest.AwaitWorkspaceBuildJob(t, templateAdminClient, workspace.LatestBuild.ID)
799+
workspace := coderdtest.CreateWorkspace(t, adminClient, admin.OrganizationID, template.ID)
800+
coderdtest.AwaitWorkspaceBuildJob(t, adminClient, workspace.LatestBuild.ID)
723801

724802
// Create workspace build
725803
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
726804
defer cancel()
727805

728-
build, err := templateAdminClient.CreateWorkspaceBuild(ctx, workspace.ID, codersdk.CreateWorkspaceBuildRequest{
806+
build, err := adminClient.CreateWorkspaceBuild(ctx, workspace.ID, codersdk.CreateWorkspaceBuildRequest{
729807
TemplateVersionID: workspace.LatestBuild.TemplateVersionID,
730808
Transition: codersdk.WorkspaceTransitionStart,
731809
ProvisionerState: []byte(" "),
732810
LogLevel: "debug",
733811
})
734812
require.Nil(t, err)
735813

736-
build = coderdtest.AwaitWorkspaceBuildJob(t, templateAdminClient, build.ID)
814+
build = coderdtest.AwaitWorkspaceBuildJob(t, adminClient, build.ID)
737815

738816
// Watch for incoming logs
739-
logs, closer, err := templateAdminClient.WorkspaceBuildLogsAfter(ctx, build.ID, 0)
817+
logs, closer, err := adminClient.WorkspaceBuildLogsAfter(ctx, build.ID, 0)
740818
require.NoError(t, err)
741819
defer closer.Close()
742820

coderd/wsbuilder/wsbuilder.go

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,13 @@ import (
3434
// build, job, err := b.Build(...)
3535
type Builder struct {
3636
// settings that control the kind of build you get
37-
workspace database.Workspace
38-
trans database.WorkspaceTransition
39-
version versionTarget
40-
state stateTarget
41-
logLevel string
37+
workspace database.Workspace
38+
trans database.WorkspaceTransition
39+
version versionTarget
40+
state stateTarget
41+
logLevel string
42+
deploymentValues *codersdk.DeploymentValues
43+
4244
richParameterValues []codersdk.WorkspaceBuildParameter
4345
initiator uuid.UUID
4446
reason database.BuildReason
@@ -128,6 +130,12 @@ func (b Builder) LogLevel(l string) Builder {
128130
return b
129131
}
130132

133+
func (b Builder) DeploymentValues(dv *codersdk.DeploymentValues) Builder {
134+
// nolint: revive
135+
b.deploymentValues = dv
136+
return b
137+
}
138+
131139
func (b Builder) Initiator(u uuid.UUID) Builder {
132140
// nolint: revive
133141
b.initiator = u
@@ -638,11 +646,19 @@ func (b *Builder) authorize(authFunc func(action rbac.Action, object rbac.Object
638646
}
639647
}
640648

641-
if b.logLevel != "" && !authFunc(rbac.ActionUpdate, template) {
649+
if b.logLevel != "" && !authFunc(rbac.ActionRead, rbac.ResourceDeploymentValues) {
650+
return BuildError{
651+
http.StatusBadRequest,
652+
"Workspace builds with a custom log level are restricted to administrators only.",
653+
xerrors.New("Workspace builds with a custom log level are restricted to administrators only."),
654+
}
655+
}
656+
657+
if b.logLevel != "" && b.deploymentValues != nil && !b.deploymentValues.EnableTerraformDebugMode {
642658
return BuildError{
643659
http.StatusBadRequest,
644-
"Workspace builds with a custom log level are restricted to template authors only.",
645-
xerrors.New("Workspace builds with a custom log level are restricted to template authors only."),
660+
"Terraform debug mode is disabled in the deployment configuration.",
661+
xerrors.New("Terraform debug mode is disabled in the deployment configuration."),
646662
}
647663
}
648664
return nil

codersdk/deployment.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ type DeploymentValues struct {
166166
WgtunnelHost clibase.String `json:"wgtunnel_host,omitempty" typescript:",notnull"`
167167
DisableOwnerWorkspaceExec clibase.Bool `json:"disable_owner_workspace_exec,omitempty" typescript:",notnull"`
168168
ProxyHealthStatusInterval clibase.Duration `json:"proxy_health_status_interval,omitempty" typescript:",notnull"`
169+
EnableTerraformDebugMode clibase.Bool `json:"enable_terraform_debug_mode,omitempty" typescript:",notnull"`
169170

170171
Config clibase.YAMLConfigPath `json:"config,omitempty" typescript:",notnull"`
171172
WriteConfig clibase.Bool `json:"write_config,omitempty" typescript:",notnull"`
@@ -1216,10 +1217,20 @@ when required by your organization's security policy.`,
12161217
YAML: "stackdriverPath",
12171218
Annotations: clibase.Annotations{}.Mark(annotationExternalProxies, "true"),
12181219
},
1220+
{
1221+
Name: "Enable Terraform debug mode",
1222+
Description: "Allow administrators to enable Terraform debug output.",
1223+
Flag: "enable-terraform-debug-mode",
1224+
Env: "CODER_ENABLE_TERRAFORM_DEBUG_MODE",
1225+
Default: "false",
1226+
Value: &c.EnableTerraformDebugMode,
1227+
Group: &deploymentGroupIntrospectionLogging,
1228+
YAML: "enableTerraformDebugMode",
1229+
},
12191230
// ☢️ Dangerous settings
12201231
{
1221-
Name: "DANGEROUS: Allow all CORs requests",
1222-
Description: "For security reasons, CORs requests are blocked except between workspace apps owned by the same user. If external requests are required, setting this to true will set all cors headers as '*'. This should never be used in production.",
1232+
Name: "DANGEROUS: Allow all CORS requests",
1233+
Description: "For security reasons, CORS requests are blocked except between workspace apps owned by the same user. If external requests are required, setting this to true will set all cors headers as '*'. This should never be used in production.",
12231234
Flag: "dangerous-allow-cors-requests",
12241235
Env: "CODER_DANGEROUS_ALLOW_CORS_REQUESTS",
12251236
Hidden: true, // Hidden, should only be used by yarn dev server

docs/api/general.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ curl -X GET http://coder-server:8080/api/v2/deployment/config \
197197
"disable_path_apps": true,
198198
"disable_session_expiry_refresh": true,
199199
"enable_oauth_account_conversion": true,
200+
"enable_terraform_debug_mode": true,
200201
"experiments": ["string"],
201202
"git_auth": {
202203
"value": [

docs/api/schemas.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1894,6 +1894,7 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in
18941894
"disable_path_apps": true,
18951895
"disable_session_expiry_refresh": true,
18961896
"enable_oauth_account_conversion": true,
1897+
"enable_terraform_debug_mode": true,
18971898
"experiments": ["string"],
18981899
"git_auth": {
18991900
"value": [
@@ -2226,6 +2227,7 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in
22262227
"disable_path_apps": true,
22272228
"disable_session_expiry_refresh": true,
22282229
"enable_oauth_account_conversion": true,
2230+
"enable_terraform_debug_mode": true,
22292231
"experiments": ["string"],
22302232
"git_auth": {
22312233
"value": [
@@ -2421,6 +2423,7 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in
24212423
| `disable_path_apps` | boolean | false | | |
24222424
| `disable_session_expiry_refresh` | boolean | false | | |
24232425
| `enable_oauth_account_conversion` | boolean | false | | |
2426+
| `enable_terraform_debug_mode` | boolean | false | | |
24242427
| `experiments` | array of string | false | | |
24252428
| `git_auth` | [clibase.Struct-array_codersdk_GitAuthConfig](#clibasestruct-array_codersdk_gitauthconfig) | false | | |
24262429
| `http_address` | string | false | | Http address is a string because it may be set to zero to disable. |

docs/cli/server.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,17 @@ Disable workspace apps that are not served from subdomains. Path-based apps can
223223

224224
Disable automatic session expiry bumping due to activity. This forces all sessions to become invalid after the session expiry duration has been reached.
225225

226+
### --enable-terraform-debug-mode
227+
228+
| | |
229+
| ----------- | ----------------------------------------------------------- |
230+
| Type | <code>bool</code> |
231+
| Environment | <code>$CODER_ENABLE_TERRAFORM_DEBUG_MODE</code> |
232+
| YAML | <code>introspection.logging.enableTerraformDebugMode</code> |
233+
| Default | <code>false</code> |
234+
235+
Allow administrators to enable Terraform debug output.
236+
226237
### --swagger-enable
227238

228239
| | |

enterprise/cli/testdata/coder_server_--help.golden

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ Use a YAML configuration file when your server launch become unwieldy.
7474
Write out the current server config as YAML to stdout.
7575

7676
Introspection / Logging Options
77+
--enable-terraform-debug-mode bool, $CODER_ENABLE_TERRAFORM_DEBUG_MODE (default: false)
78+
Allow administrators to enable Terraform debug output.
79+
7780
--log-human string, $CODER_LOGGING_HUMAN (default: /dev/stderr)
7881
Output human-readable logs to a given file.
7982

0 commit comments

Comments
 (0)