mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat!: move workspace renames behind flag, disable by default (#11189)
This commit is contained in:
Generated
+6
@@ -8558,6 +8558,9 @@ const docTemplate = `{
|
||||
"agent_stat_refresh_interval": {
|
||||
"type": "integer"
|
||||
},
|
||||
"allow_workspace_renames": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"autobuild_poll_interval": {
|
||||
"type": "integer"
|
||||
},
|
||||
@@ -11443,6 +11446,9 @@ const docTemplate = `{
|
||||
"codersdk.Workspace": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"allow_renames": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"automatic_updates": {
|
||||
"enum": [
|
||||
"always",
|
||||
|
||||
Generated
+6
@@ -7642,6 +7642,9 @@
|
||||
"agent_stat_refresh_interval": {
|
||||
"type": "integer"
|
||||
},
|
||||
"allow_workspace_renames": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"autobuild_poll_interval": {
|
||||
"type": "integer"
|
||||
},
|
||||
@@ -10372,6 +10375,9 @@
|
||||
"codersdk.Workspace": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"allow_renames": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"automatic_updates": {
|
||||
"enum": ["always", "never"],
|
||||
"allOf": [
|
||||
|
||||
+2
-1
@@ -179,7 +179,8 @@ type Options struct {
|
||||
// This janky function is used in telemetry to parse fields out of the raw
|
||||
// JWT. It needs to be passed through like this because license parsing is
|
||||
// under the enterprise license, and can't be imported into AGPL.
|
||||
ParseLicenseClaims func(rawJWT string) (email string, trial bool, err error)
|
||||
ParseLicenseClaims func(rawJWT string) (email string, trial bool, err error)
|
||||
AllowWorkspaceRenames bool
|
||||
}
|
||||
|
||||
// @title Coder API
|
||||
|
||||
@@ -144,6 +144,7 @@ type Options struct {
|
||||
StatsBatcher *batchstats.Batcher
|
||||
|
||||
WorkspaceAppsStatsCollectorOptions workspaceapps.StatsCollectorOptions
|
||||
AllowWorkspaceRenames bool
|
||||
}
|
||||
|
||||
// New constructs a codersdk client connected to an in-memory API instance.
|
||||
@@ -449,6 +450,7 @@ func NewOptions(t testing.TB, options *Options) (func(http.Handler), context.Can
|
||||
HealthcheckRefresh: options.HealthcheckRefresh,
|
||||
StatsBatcher: options.StatsBatcher,
|
||||
WorkspaceAppsStatsCollectorOptions: options.WorkspaceAppsStatsCollectorOptions,
|
||||
AllowWorkspaceRenames: options.AllowWorkspaceRenames,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+22
-6
@@ -106,6 +106,7 @@ func (api *API) workspace(rw http.ResponseWriter, r *http.Request) {
|
||||
data.builds[0],
|
||||
data.templates[0],
|
||||
ownerName,
|
||||
api.Options.AllowWorkspaceRenames,
|
||||
))
|
||||
}
|
||||
|
||||
@@ -277,6 +278,7 @@ func (api *API) workspaceByOwnerAndName(rw http.ResponseWriter, r *http.Request)
|
||||
data.builds[0],
|
||||
data.templates[0],
|
||||
ownerName,
|
||||
api.Options.AllowWorkspaceRenames,
|
||||
))
|
||||
}
|
||||
|
||||
@@ -585,6 +587,7 @@ func (api *API) postWorkspacesByOrganization(rw http.ResponseWriter, r *http.Req
|
||||
apiBuild,
|
||||
template,
|
||||
member.Username,
|
||||
api.Options.AllowWorkspaceRenames,
|
||||
))
|
||||
}
|
||||
|
||||
@@ -628,6 +631,12 @@ func (api *API) patchWorkspace(rw http.ResponseWriter, r *http.Request) {
|
||||
// patched in the future, it's enough if one changes.
|
||||
name := workspace.Name
|
||||
if req.Name != "" || req.Name != workspace.Name {
|
||||
if !api.Options.AllowWorkspaceRenames {
|
||||
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
|
||||
Message: "Workspace renames are not allowed.",
|
||||
})
|
||||
return
|
||||
}
|
||||
name = req.Name
|
||||
}
|
||||
|
||||
@@ -917,6 +926,7 @@ func (api *API) putWorkspaceDormant(rw http.ResponseWriter, r *http.Request) {
|
||||
data.builds[0],
|
||||
data.templates[0],
|
||||
ownerName,
|
||||
api.Options.AllowWorkspaceRenames,
|
||||
))
|
||||
}
|
||||
|
||||
@@ -1242,6 +1252,7 @@ func (api *API) watchWorkspace(rw http.ResponseWriter, r *http.Request) {
|
||||
data.builds[0],
|
||||
data.templates[0],
|
||||
ownerName,
|
||||
api.Options.AllowWorkspaceRenames,
|
||||
),
|
||||
})
|
||||
}
|
||||
@@ -1293,9 +1304,10 @@ func (api *API) watchWorkspace(rw http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
type workspaceData struct {
|
||||
templates []database.Template
|
||||
builds []codersdk.WorkspaceBuild
|
||||
users []database.User
|
||||
templates []database.Template
|
||||
builds []codersdk.WorkspaceBuild
|
||||
users []database.User
|
||||
allowRenames bool
|
||||
}
|
||||
|
||||
// workspacesData only returns the data the caller can access. If the caller
|
||||
@@ -1347,9 +1359,10 @@ func (api *API) workspaceData(ctx context.Context, workspaces []database.Workspa
|
||||
}
|
||||
|
||||
return workspaceData{
|
||||
templates: templates,
|
||||
builds: apiBuilds,
|
||||
users: data.users,
|
||||
templates: templates,
|
||||
builds: apiBuilds,
|
||||
users: data.users,
|
||||
allowRenames: api.Options.AllowWorkspaceRenames,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -1392,6 +1405,7 @@ func convertWorkspaces(workspaces []database.Workspace, data workspaceData) ([]c
|
||||
build,
|
||||
template,
|
||||
owner.Username,
|
||||
data.allowRenames,
|
||||
))
|
||||
}
|
||||
return apiWorkspaces, nil
|
||||
@@ -1402,6 +1416,7 @@ func convertWorkspace(
|
||||
workspaceBuild codersdk.WorkspaceBuild,
|
||||
template database.Template,
|
||||
ownerName string,
|
||||
allowRenames bool,
|
||||
) codersdk.Workspace {
|
||||
var autostartSchedule *string
|
||||
if workspace.AutostartSchedule.Valid {
|
||||
@@ -1456,6 +1471,7 @@ func convertWorkspace(
|
||||
FailingAgents: failingAgents,
|
||||
},
|
||||
AutomaticUpdates: codersdk.AutomaticUpdates(workspace.AutomaticUpdates),
|
||||
AllowRenames: allowRenames,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -100,7 +100,10 @@ func TestWorkspace(t *testing.T) {
|
||||
|
||||
t.Run("Rename", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
|
||||
client := coderdtest.New(t, &coderdtest.Options{
|
||||
IncludeProvisionerDaemon: true,
|
||||
AllowWorkspaceRenames: true,
|
||||
})
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
|
||||
@@ -134,6 +137,29 @@ func TestWorkspace(t *testing.T) {
|
||||
require.Error(t, err, "workspace rename should have failed")
|
||||
})
|
||||
|
||||
t.Run("RenameDisabled", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, &coderdtest.Options{
|
||||
IncludeProvisionerDaemon: true,
|
||||
AllowWorkspaceRenames: false,
|
||||
})
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
ws1 := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID)
|
||||
coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, ws1.LatestBuild.ID)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitMedium)
|
||||
defer cancel()
|
||||
|
||||
want := "new-name"
|
||||
err := client.UpdateWorkspace(ctx, ws1.ID, codersdk.UpdateWorkspaceRequest{
|
||||
Name: want,
|
||||
})
|
||||
require.ErrorContains(t, err, "Workspace renames are not allowed")
|
||||
})
|
||||
|
||||
t.Run("TemplateProperties", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
|
||||
@@ -2152,7 +2178,10 @@ func TestUpdateWorkspaceAutomaticUpdates_NotFound(t *testing.T) {
|
||||
|
||||
func TestWorkspaceWatcher(t *testing.T) {
|
||||
t.Parallel()
|
||||
client, closeFunc := coderdtest.NewWithProvisionerCloser(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
|
||||
client, closeFunc := coderdtest.NewWithProvisionerCloser(t, &coderdtest.Options{
|
||||
IncludeProvisionerDaemon: true,
|
||||
AllowWorkspaceRenames: true,
|
||||
})
|
||||
defer closeFunc.Close()
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
authToken := uuid.NewString()
|
||||
|
||||
Reference in New Issue
Block a user