Skip to content

Commit 88669fd

Browse files
authored
feat: Move workspaces under organizations (#1109)
This removes split ownership for workspaces. They are now a resource of organizations and have a designated owner, which is a user. This enables simple administration for commands like: - `coder stop ben/dev` - `coder build logs colin/arch` or if we decide to allow administrators to access workspaces, they could even SSH using this syntax: `coder ssh colin/dev`.
1 parent 759fa5f commit 88669fd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+852
-638
lines changed

cli/agent_test.go

+3-4
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88

99
"github.com/coder/coder/cli/clitest"
1010
"github.com/coder/coder/coderd/coderdtest"
11-
"github.com/coder/coder/codersdk"
1211
"github.com/coder/coder/provisioner/echo"
1312
"github.com/coder/coder/provisionersdk/proto"
1413
)
@@ -44,7 +43,7 @@ func TestWorkspaceAgent(t *testing.T) {
4443
})
4544
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
4645
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
47-
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
46+
workspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID)
4847
coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
4948

5049
cmd, _ := clitest.New(t, "agent", "--auth", "azure-instance-identity", "--url", client.URL.String())
@@ -98,7 +97,7 @@ func TestWorkspaceAgent(t *testing.T) {
9897
})
9998
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
10099
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
101-
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
100+
workspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID)
102101
coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
103102

104103
cmd, _ := clitest.New(t, "agent", "--auth", "aws-instance-identity", "--url", client.URL.String())
@@ -152,7 +151,7 @@ func TestWorkspaceAgent(t *testing.T) {
152151
})
153152
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
154153
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
155-
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
154+
workspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID)
156155
coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
157156

158157
cmd, _ := clitest.New(t, "agent", "--auth", "google-instance-identity", "--url", client.URL.String())

cli/configssh.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ func configSSH() *cobra.Command {
4242
if err != nil {
4343
return err
4444
}
45+
organization, err := currentOrganization(cmd, client)
46+
if err != nil {
47+
return err
48+
}
4549
if strings.HasPrefix(sshConfigFile, "~/") {
4650
dirname, _ := os.UserHomeDir()
4751
sshConfigFile = filepath.Join(dirname, sshConfigFile[2:])
@@ -55,7 +59,7 @@ func configSSH() *cobra.Command {
5559
sshConfigContent = sshConfigContent[:startIndex-1] + sshConfigContent[endIndex+len(sshEndToken):]
5660
}
5761

58-
workspaces, err := client.WorkspacesByUser(cmd.Context(), codersdk.Me)
62+
workspaces, err := client.WorkspacesByOwner(cmd.Context(), organization.ID, codersdk.Me)
5963
if err != nil {
6064
return err
6165
}

cli/configssh_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ func TestConfigSSH(t *testing.T) {
6767
})
6868
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
6969
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
70-
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
70+
workspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID)
7171
coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
7272
agentClient := codersdk.New(client.URL)
7373
agentClient.SessionToken = authToken

cli/gitssh_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ func TestGitSSH(t *testing.T) {
5757
})
5858
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
5959
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
60-
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
60+
workspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID)
6161
coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
6262

6363
// start workspace agent

cli/parameters.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ func parseScopeAndID(ctx context.Context, client *codersdk.Client, organization
5353
}
5454
scopeID = user.ID
5555
case codersdk.ParameterWorkspace:
56-
workspace, err := client.WorkspaceByName(ctx, codersdk.Me, name)
56+
workspace, err := client.WorkspaceByOwnerAndName(ctx, organization.ID, codersdk.Me, name)
5757
if err != nil {
5858
return scope, uuid.Nil, err
5959
}

cli/server.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,11 @@ func server() *cobra.Command {
327327
_, _ = fmt.Fprintln(cmd.OutOrStdout(), "\n\n"+cliui.Styles.Bold.Render("Interrupt caught. Gracefully exiting..."))
328328

329329
if dev {
330-
workspaces, err := client.WorkspacesByUser(cmd.Context(), codersdk.Me)
330+
organizations, err := client.OrganizationsByUser(cmd.Context(), codersdk.Me)
331+
if err != nil {
332+
return xerrors.Errorf("get organizations: %w", err)
333+
}
334+
workspaces, err := client.WorkspacesByOwner(cmd.Context(), organizations[0].ID, codersdk.Me)
331335
if err != nil {
332336
return xerrors.Errorf("get workspaces: %w", err)
333337
}

cli/server_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ func TestServer(t *testing.T) {
190190
version := coderdtest.CreateTemplateVersion(t, client, orgs[0].ID, nil)
191191
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
192192
template := coderdtest.CreateTemplate(t, client, orgs[0].ID, version.ID)
193-
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
193+
workspace := coderdtest.CreateWorkspace(t, client, orgs[0].ID, template.ID)
194194
coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
195195

196196
require.NoError(t, err)

cli/ssh.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,13 @@ func ssh() *cobra.Command {
3333
if err != nil {
3434
return err
3535
}
36+
organization, err := currentOrganization(cmd, client)
37+
if err != nil {
38+
return err
39+
}
3640

3741
workspaceParts := strings.Split(args[0], ".")
38-
workspace, err := client.WorkspaceByName(cmd.Context(), codersdk.Me, workspaceParts[0])
42+
workspace, err := client.WorkspaceByOwnerAndName(cmd.Context(), organization.ID, codersdk.Me, workspaceParts[0])
3943
if err != nil {
4044
return err
4145
}

cli/ssh_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ func TestSSH(t *testing.T) {
5252
})
5353
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
5454
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
55-
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
55+
workspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID)
5656
cmd, root := clitest.New(t, "ssh", workspace.Name)
5757
clitest.SetupConfig(t, client, root)
5858
doneChan := make(chan struct{})
@@ -105,7 +105,7 @@ func TestSSH(t *testing.T) {
105105
})
106106
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
107107
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
108-
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
108+
workspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID)
109109
go func() {
110110
// Run this async so the SSH command has to wait for
111111
// the build and agent to connect!

cli/workspaceautostart.go

+10-2
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,18 @@ func workspaceAutostartEnable() *cobra.Command {
4646
if err != nil {
4747
return err
4848
}
49+
organization, err := currentOrganization(cmd, client)
50+
if err != nil {
51+
return err
52+
}
4953

5054
spec := fmt.Sprintf("CRON_TZ=%s %s %s * * %s", autostartTimezone, autostartMinute, autostartHour, autostartDayOfWeek)
5155
validSchedule, err := schedule.Weekly(spec)
5256
if err != nil {
5357
return err
5458
}
5559

56-
workspace, err := client.WorkspaceByName(cmd.Context(), codersdk.Me, args[0])
60+
workspace, err := client.WorkspaceByOwnerAndName(cmd.Context(), organization.ID, codersdk.Me, args[0])
5761
if err != nil {
5862
return err
5963
}
@@ -92,8 +96,12 @@ func workspaceAutostartDisable() *cobra.Command {
9296
if err != nil {
9397
return err
9498
}
99+
organization, err := currentOrganization(cmd, client)
100+
if err != nil {
101+
return err
102+
}
95103

96-
workspace, err := client.WorkspaceByName(cmd.Context(), codersdk.Me, args[0])
104+
workspace, err := client.WorkspaceByOwnerAndName(cmd.Context(), organization.ID, codersdk.Me, args[0])
97105
if err != nil {
98106
return err
99107
}

cli/workspaceautostart_test.go

+2-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111

1212
"github.com/coder/coder/cli/clitest"
1313
"github.com/coder/coder/coderd/coderdtest"
14-
"github.com/coder/coder/codersdk"
1514
)
1615

1716
func TestWorkspaceAutostart(t *testing.T) {
@@ -28,7 +27,7 @@ func TestWorkspaceAutostart(t *testing.T) {
2827
version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
2928
_ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
3029
project = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
31-
workspace = coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
30+
workspace = coderdtest.CreateWorkspace(t, client, user.OrganizationID, project.ID)
3231
tz = "Europe/Dublin"
3332
cmdArgs = []string{"workspaces", "autostart", "enable", workspace.Name, "--minute", "30", "--hour", "9", "--days", "1-5", "--tz", tz}
3433
sched = "CRON_TZ=Europe/Dublin 30 9 * * 1-5"
@@ -110,7 +109,7 @@ func TestWorkspaceAutostart(t *testing.T) {
110109
version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
111110
_ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
112111
project = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
113-
workspace = coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
112+
workspace = coderdtest.CreateWorkspace(t, client, user.OrganizationID, project.ID)
114113
)
115114

116115
// check current TZ env var

cli/workspaceautostop.go

+10-2
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,18 @@ func workspaceAutostopEnable() *cobra.Command {
4646
if err != nil {
4747
return err
4848
}
49+
organization, err := currentOrganization(cmd, client)
50+
if err != nil {
51+
return err
52+
}
4953

5054
spec := fmt.Sprintf("CRON_TZ=%s %s %s * * %s", autostopTimezone, autostopMinute, autostopHour, autostopDayOfWeek)
5155
validSchedule, err := schedule.Weekly(spec)
5256
if err != nil {
5357
return err
5458
}
5559

56-
workspace, err := client.WorkspaceByName(cmd.Context(), codersdk.Me, args[0])
60+
workspace, err := client.WorkspaceByOwnerAndName(cmd.Context(), organization.ID, codersdk.Me, args[0])
5761
if err != nil {
5862
return err
5963
}
@@ -92,8 +96,12 @@ func workspaceAutostopDisable() *cobra.Command {
9296
if err != nil {
9397
return err
9498
}
99+
organization, err := currentOrganization(cmd, client)
100+
if err != nil {
101+
return err
102+
}
95103

96-
workspace, err := client.WorkspaceByName(cmd.Context(), codersdk.Me, args[0])
104+
workspace, err := client.WorkspaceByOwnerAndName(cmd.Context(), organization.ID, codersdk.Me, args[0])
97105
if err != nil {
98106
return err
99107
}

cli/workspaceautostop_test.go

+2-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111

1212
"github.com/coder/coder/cli/clitest"
1313
"github.com/coder/coder/coderd/coderdtest"
14-
"github.com/coder/coder/codersdk"
1514
)
1615

1716
func TestWorkspaceAutostop(t *testing.T) {
@@ -28,7 +27,7 @@ func TestWorkspaceAutostop(t *testing.T) {
2827
version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
2928
_ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
3029
project = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
31-
workspace = coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
30+
workspace = coderdtest.CreateWorkspace(t, client, user.OrganizationID, project.ID)
3231
cmdArgs = []string{"workspaces", "autostop", "enable", workspace.Name, "--minute", "30", "--hour", "17", "--days", "1-5", "--tz", "Europe/Dublin"}
3332
sched = "CRON_TZ=Europe/Dublin 30 17 * * 1-5"
3433
stdoutBuf = &bytes.Buffer{}
@@ -109,7 +108,7 @@ func TestWorkspaceAutostop(t *testing.T) {
109108
version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
110109
_ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
111110
project = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
112-
workspace = coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
111+
workspace = coderdtest.CreateWorkspace(t, client, user.OrganizationID, project.ID)
113112
)
114113

115114
// check current TZ env var

cli/workspacecreate.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func workspaceCreate() *cobra.Command {
4141
workspaceName, err = cliui.Prompt(cmd, cliui.PromptOptions{
4242
Text: "Specify a name for your workspace:",
4343
Validate: func(workspaceName string) error {
44-
_, err = client.WorkspaceByName(cmd.Context(), codersdk.Me, workspaceName)
44+
_, err = client.WorkspaceByOwnerAndName(cmd.Context(), organization.ID, codersdk.Me, workspaceName)
4545
if err == nil {
4646
return xerrors.Errorf("A workspace already exists named %q!", workspaceName)
4747
}
@@ -53,7 +53,7 @@ func workspaceCreate() *cobra.Command {
5353
}
5454
}
5555

56-
_, err = client.WorkspaceByName(cmd.Context(), codersdk.Me, workspaceName)
56+
_, err = client.WorkspaceByOwnerAndName(cmd.Context(), organization.ID, codersdk.Me, workspaceName)
5757
if err == nil {
5858
return xerrors.Errorf("A workspace already exists named %q!", workspaceName)
5959
}
@@ -162,7 +162,7 @@ func workspaceCreate() *cobra.Command {
162162
}
163163

164164
before := time.Now()
165-
workspace, err := client.CreateWorkspace(cmd.Context(), codersdk.Me, codersdk.CreateWorkspaceRequest{
165+
workspace, err := client.CreateWorkspace(cmd.Context(), organization.ID, codersdk.CreateWorkspaceRequest{
166166
TemplateID: template.ID,
167167
Name: workspaceName,
168168
ParameterValues: parameters,

cli/workspacedelete.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,11 @@ func workspaceDelete() *cobra.Command {
2121
if err != nil {
2222
return err
2323
}
24-
workspace, err := client.WorkspaceByName(cmd.Context(), codersdk.Me, args[0])
24+
organization, err := currentOrganization(cmd, client)
25+
if err != nil {
26+
return err
27+
}
28+
workspace, err := client.WorkspaceByOwnerAndName(cmd.Context(), organization.ID, codersdk.Me, args[0])
2529
if err != nil {
2630
return err
2731
}

cli/workspacelist.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@ func workspaceList() *cobra.Command {
2020
if err != nil {
2121
return err
2222
}
23-
workspaces, err := client.WorkspacesByUser(cmd.Context(), codersdk.Me)
23+
organization, err := currentOrganization(cmd, client)
24+
if err != nil {
25+
return err
26+
}
27+
workspaces, err := client.WorkspacesByOwner(cmd.Context(), organization.ID, codersdk.Me)
2428
if err != nil {
2529
return err
2630
}

cli/workspaces.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@ func validArgsWorkspaceName(cmd *cobra.Command, _ []string, toComplete string) (
3232
if err != nil {
3333
return nil, cobra.ShellCompDirectiveError
3434
}
35-
workspaces, err := client.WorkspacesByUser(cmd.Context(), codersdk.Me)
35+
organization, err := currentOrganization(cmd, client)
36+
if err != nil {
37+
return nil, cobra.ShellCompDirectiveError
38+
}
39+
workspaces, err := client.WorkspacesByOwner(cmd.Context(), organization.ID, codersdk.Me)
3640
if err != nil {
3741
return nil, cobra.ShellCompDirectiveError
3842
}

cli/workspaceshow.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ func workspaceShow() *cobra.Command {
1717
if err != nil {
1818
return err
1919
}
20-
workspace, err := client.WorkspaceByName(cmd.Context(), codersdk.Me, args[0])
20+
organization, err := currentOrganization(cmd, client)
21+
if err != nil {
22+
return err
23+
}
24+
workspace, err := client.WorkspaceByOwnerAndName(cmd.Context(), organization.ID, codersdk.Me, args[0])
2125
if err != nil {
2226
return xerrors.Errorf("get workspace: %w", err)
2327
}

cli/workspacestart.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@ func workspaceStart() *cobra.Command {
2020
if err != nil {
2121
return err
2222
}
23-
workspace, err := client.WorkspaceByName(cmd.Context(), codersdk.Me, args[0])
23+
organization, err := currentOrganization(cmd, client)
24+
if err != nil {
25+
return err
26+
}
27+
workspace, err := client.WorkspaceByOwnerAndName(cmd.Context(), organization.ID, codersdk.Me, args[0])
2428
if err != nil {
2529
return err
2630
}

cli/workspacestop.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@ func workspaceStop() *cobra.Command {
2020
if err != nil {
2121
return err
2222
}
23-
workspace, err := client.WorkspaceByName(cmd.Context(), codersdk.Me, args[0])
23+
organization, err := currentOrganization(cmd, client)
24+
if err != nil {
25+
return err
26+
}
27+
workspace, err := client.WorkspaceByOwnerAndName(cmd.Context(), organization.ID, codersdk.Me, args[0])
2428
if err != nil {
2529
return err
2630
}

cli/workspaceupdate.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ func workspaceUpdate() *cobra.Command {
1717
if err != nil {
1818
return err
1919
}
20-
workspace, err := client.WorkspaceByName(cmd.Context(), codersdk.Me, args[0])
20+
organization, err := currentOrganization(cmd, client)
21+
if err != nil {
22+
return err
23+
}
24+
workspace, err := client.WorkspaceByOwnerAndName(cmd.Context(), organization.ID, codersdk.Me, args[0])
2125
if err != nil {
2226
return err
2327
}

cmd/templater/main.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ func parse(cmd *cobra.Command, parameters []codersdk.CreateParameterRequest) err
171171
return err
172172
}
173173

174-
workspace, err := client.CreateWorkspace(cmd.Context(), created.UserID, codersdk.CreateWorkspaceRequest{
174+
workspace, err := client.CreateWorkspace(cmd.Context(), created.OrganizationID, codersdk.CreateWorkspaceRequest{
175175
TemplateID: template.ID,
176176
Name: "example",
177177
})

0 commit comments

Comments
 (0)