mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat!: patchTemplateMeta to use optional fields (#24984)
Closes https://github.com/coder/coder/issues/13112 **Breaking Change**: Removed status code `StatusNotModified` when no diffs occur in a patch. Now the patch is always applied and a template is always returned.
This commit is contained in:
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/coder/coder/v2/cli/clitest"
|
||||
"github.com/coder/coder/v2/coderd/coderdtest"
|
||||
"github.com/coder/coder/v2/coderd/rbac"
|
||||
"github.com/coder/coder/v2/coderd/util/ptr"
|
||||
"github.com/coder/coder/v2/codersdk"
|
||||
"github.com/coder/coder/v2/enterprise/coderd/coderdenttest"
|
||||
"github.com/coder/coder/v2/enterprise/coderd/license"
|
||||
@@ -46,7 +47,7 @@ func TestStart(t *testing.T) {
|
||||
coderdtest.AwaitTemplateVersionJobCompleted(t, templateAdminClient, oldVersion.ID)
|
||||
require.Equal(t, oldVersion.ID, template.ActiveVersionID)
|
||||
template = coderdtest.UpdateTemplateMeta(t, templateAdminClient, template.ID, codersdk.UpdateTemplateMeta{
|
||||
RequireActiveVersion: true,
|
||||
RequireActiveVersion: ptr.Ref(true),
|
||||
})
|
||||
require.True(t, template.RequireActiveVersion)
|
||||
|
||||
|
||||
@@ -218,20 +218,20 @@ func TestTemplateEdit(t *testing.T) {
|
||||
}
|
||||
|
||||
template, err := ownerClient.UpdateTemplateMeta(ctx, dbtemplate.ID, codersdk.UpdateTemplateMeta{
|
||||
Name: expectedName,
|
||||
Name: ptr.Ref(expectedName),
|
||||
DisplayName: &expectedDisplayName,
|
||||
Description: &expectedDescription,
|
||||
Icon: &expectedIcon,
|
||||
DefaultTTLMillis: expectedDefaultTTLMillis,
|
||||
AllowUserAutostop: expectedAllowAutostop,
|
||||
AllowUserAutostart: expectedAllowAutostart,
|
||||
FailureTTLMillis: expectedFailureTTLMillis,
|
||||
TimeTilDormantMillis: expectedDormancyMillis,
|
||||
TimeTilDormantAutoDeleteMillis: expectedAutoDeleteMillis,
|
||||
RequireActiveVersion: expectedRequireActiveVersion,
|
||||
DefaultTTLMillis: ptr.Ref(expectedDefaultTTLMillis),
|
||||
AllowUserAutostop: ptr.Ref(expectedAllowAutostop),
|
||||
AllowUserAutostart: ptr.Ref(expectedAllowAutostart),
|
||||
FailureTTLMillis: ptr.Ref(expectedFailureTTLMillis),
|
||||
TimeTilDormantMillis: ptr.Ref(expectedDormancyMillis),
|
||||
TimeTilDormantAutoDeleteMillis: ptr.Ref(expectedAutoDeleteMillis),
|
||||
RequireActiveVersion: ptr.Ref(expectedRequireActiveVersion),
|
||||
DeprecationMessage: ptr.Ref(deprecationMessage),
|
||||
DisableEveryoneGroupAccess: expectedDisableEveryone,
|
||||
AllowUserCancelWorkspaceJobs: expectedAllowCancelJobs,
|
||||
DisableEveryoneGroupAccess: ptr.Ref(expectedDisableEveryone),
|
||||
AllowUserCancelWorkspaceJobs: ptr.Ref(expectedAllowCancelJobs),
|
||||
AutostartRequirement: &codersdk.TemplateAutostartRequirement{
|
||||
DaysOfWeek: expectedAutostartDaysOfWeek,
|
||||
},
|
||||
@@ -266,20 +266,20 @@ func TestTemplateEdit(t *testing.T) {
|
||||
expectedAutoStopWeeks = 2
|
||||
|
||||
template, err = ownerClient.UpdateTemplateMeta(ctx, dbtemplate.ID, codersdk.UpdateTemplateMeta{
|
||||
Name: expectedName,
|
||||
Name: ptr.Ref(expectedName),
|
||||
DisplayName: &expectedDisplayName,
|
||||
Description: &expectedDescription,
|
||||
Icon: &expectedIcon,
|
||||
DefaultTTLMillis: expectedDefaultTTLMillis,
|
||||
AllowUserAutostop: expectedAllowAutostop,
|
||||
AllowUserAutostart: expectedAllowAutostart,
|
||||
FailureTTLMillis: expectedFailureTTLMillis,
|
||||
TimeTilDormantMillis: expectedDormancyMillis,
|
||||
TimeTilDormantAutoDeleteMillis: expectedAutoDeleteMillis,
|
||||
RequireActiveVersion: expectedRequireActiveVersion,
|
||||
DefaultTTLMillis: ptr.Ref(expectedDefaultTTLMillis),
|
||||
AllowUserAutostop: ptr.Ref(expectedAllowAutostop),
|
||||
AllowUserAutostart: ptr.Ref(expectedAllowAutostart),
|
||||
FailureTTLMillis: ptr.Ref(expectedFailureTTLMillis),
|
||||
TimeTilDormantMillis: ptr.Ref(expectedDormancyMillis),
|
||||
TimeTilDormantAutoDeleteMillis: ptr.Ref(expectedAutoDeleteMillis),
|
||||
RequireActiveVersion: ptr.Ref(expectedRequireActiveVersion),
|
||||
DeprecationMessage: ptr.Ref(deprecationMessage),
|
||||
DisableEveryoneGroupAccess: expectedDisableEveryone,
|
||||
AllowUserCancelWorkspaceJobs: expectedAllowCancelJobs,
|
||||
DisableEveryoneGroupAccess: ptr.Ref(expectedDisableEveryone),
|
||||
AllowUserCancelWorkspaceJobs: ptr.Ref(expectedAllowCancelJobs),
|
||||
AutostartRequirement: &codersdk.TemplateAutostartRequirement{
|
||||
DaysOfWeek: expectedAutostartDaysOfWeek,
|
||||
},
|
||||
|
||||
@@ -186,14 +186,16 @@ func TestTemplates(t *testing.T) {
|
||||
|
||||
ctx := testutil.Context(t, testutil.WaitLong)
|
||||
|
||||
// OK
|
||||
// OK: setting the same level is a no-op under the new PATCH semantics
|
||||
// (304 Not Modified) but must not be a server error.
|
||||
var level codersdk.WorkspaceAgentPortShareLevel = codersdk.WorkspaceAgentPortShareLevelPublic
|
||||
updated, err := client.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{
|
||||
_, err = client.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{
|
||||
MaxPortShareLevel: &level,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, level, updated.MaxPortShareLevel)
|
||||
|
||||
template, err = client.Template(ctx, template.ID)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, level, template.MaxPortShareLevel)
|
||||
// Invalid level
|
||||
level = "invalid"
|
||||
_, err = client.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{
|
||||
@@ -258,7 +260,7 @@ func TestTemplates(t *testing.T) {
|
||||
|
||||
ctx := testutil.Context(t, testutil.WaitLong)
|
||||
updated, err := anotherClient.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{
|
||||
Name: template.Name,
|
||||
Name: ptr.Ref(template.Name),
|
||||
DisplayName: &template.DisplayName,
|
||||
Description: &template.Description,
|
||||
Icon: &template.Icon,
|
||||
@@ -275,7 +277,7 @@ func TestTemplates(t *testing.T) {
|
||||
|
||||
// Ensure a missing field is a noop
|
||||
updated, err = anotherClient.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{
|
||||
Name: template.Name,
|
||||
Name: ptr.Ref(template.Name),
|
||||
DisplayName: &template.DisplayName,
|
||||
Description: &template.Description,
|
||||
Icon: ptr.Ref(template.Icon + "something"),
|
||||
@@ -312,7 +314,7 @@ func TestTemplates(t *testing.T) {
|
||||
|
||||
ctx := testutil.Context(t, testutil.WaitLong)
|
||||
_, err := anotherClient.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{
|
||||
Name: template.Name,
|
||||
Name: ptr.Ref(template.Name),
|
||||
DisplayName: &template.DisplayName,
|
||||
Description: &template.Description,
|
||||
Icon: &template.Icon,
|
||||
@@ -348,12 +350,12 @@ func TestTemplates(t *testing.T) {
|
||||
|
||||
ctx := context.Background()
|
||||
updated, err := anotherClient.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{
|
||||
Name: template.Name,
|
||||
Name: ptr.Ref(template.Name),
|
||||
DisplayName: &template.DisplayName,
|
||||
Description: &template.Description,
|
||||
Icon: &template.Icon,
|
||||
AllowUserCancelWorkspaceJobs: template.AllowUserCancelWorkspaceJobs,
|
||||
DefaultTTLMillis: time.Hour.Milliseconds(),
|
||||
AllowUserCancelWorkspaceJobs: ptr.Ref(template.AllowUserCancelWorkspaceJobs),
|
||||
DefaultTTLMillis: ptr.Ref(time.Hour.Milliseconds()),
|
||||
AutostopRequirement: &codersdk.TemplateAutostopRequirement{
|
||||
DaysOfWeek: []string{"monday", "saturday"},
|
||||
Weeks: 3,
|
||||
@@ -402,14 +404,14 @@ func TestTemplates(t *testing.T) {
|
||||
)
|
||||
|
||||
updated, err := anotherClient.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{
|
||||
Name: template.Name,
|
||||
Name: ptr.Ref(template.Name),
|
||||
DisplayName: &template.DisplayName,
|
||||
Description: &template.Description,
|
||||
Icon: &template.Icon,
|
||||
AllowUserCancelWorkspaceJobs: template.AllowUserCancelWorkspaceJobs,
|
||||
TimeTilDormantMillis: inactivityTTL.Milliseconds(),
|
||||
FailureTTLMillis: failureTTL.Milliseconds(),
|
||||
TimeTilDormantAutoDeleteMillis: dormantTTL.Milliseconds(),
|
||||
AllowUserCancelWorkspaceJobs: ptr.Ref(template.AllowUserCancelWorkspaceJobs),
|
||||
TimeTilDormantMillis: ptr.Ref(inactivityTTL.Milliseconds()),
|
||||
FailureTTLMillis: ptr.Ref(failureTTL.Milliseconds()),
|
||||
TimeTilDormantAutoDeleteMillis: ptr.Ref(dormantTTL.Milliseconds()),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, failureTTL.Milliseconds(), updated.FailureTTLMillis)
|
||||
@@ -471,14 +473,14 @@ func TestTemplates(t *testing.T) {
|
||||
// nolint: paralleltest // context is from parent t.Run
|
||||
t.Run(c.Name, func(t *testing.T) {
|
||||
_, err := anotherClient.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{
|
||||
Name: template.Name,
|
||||
Name: ptr.Ref(template.Name),
|
||||
DisplayName: &template.DisplayName,
|
||||
Description: &template.Description,
|
||||
Icon: &template.Icon,
|
||||
AllowUserCancelWorkspaceJobs: template.AllowUserCancelWorkspaceJobs,
|
||||
TimeTilDormantMillis: c.TimeTilDormantMS,
|
||||
FailureTTLMillis: c.FailureTTLMS,
|
||||
TimeTilDormantAutoDeleteMillis: c.DormantAutoDeleteMS,
|
||||
AllowUserCancelWorkspaceJobs: ptr.Ref(template.AllowUserCancelWorkspaceJobs),
|
||||
TimeTilDormantMillis: ptr.Ref(c.TimeTilDormantMS),
|
||||
FailureTTLMillis: ptr.Ref(c.FailureTTLMS),
|
||||
TimeTilDormantAutoDeleteMillis: ptr.Ref(c.DormantAutoDeleteMS),
|
||||
})
|
||||
require.Error(t, err)
|
||||
cerr, ok := codersdk.AsError(err)
|
||||
@@ -529,7 +531,7 @@ func TestTemplates(t *testing.T) {
|
||||
|
||||
dormantTTL := time.Minute
|
||||
updated, err := anotherClient.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{
|
||||
TimeTilDormantAutoDeleteMillis: dormantTTL.Milliseconds(),
|
||||
TimeTilDormantAutoDeleteMillis: ptr.Ref(dormantTTL.Milliseconds()),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, dormantTTL.Milliseconds(), updated.TimeTilDormantAutoDeleteMillis)
|
||||
@@ -547,7 +549,7 @@ func TestTemplates(t *testing.T) {
|
||||
// Disable the time_til_dormant_auto_delete on the template, then we can assert that the workspaces
|
||||
// no longer have a deleting_at field.
|
||||
updated, err = anotherClient.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{
|
||||
TimeTilDormantAutoDeleteMillis: 0,
|
||||
TimeTilDormantAutoDeleteMillis: ptr.Ref[int64](0),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.EqualValues(t, 0, updated.TimeTilDormantAutoDeleteMillis)
|
||||
@@ -604,8 +606,8 @@ func TestTemplates(t *testing.T) {
|
||||
dormantTTL := time.Minute
|
||||
//nolint:gocritic // non-template-admin cannot update template meta
|
||||
updated, err := client.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{
|
||||
TimeTilDormantAutoDeleteMillis: dormantTTL.Milliseconds(),
|
||||
UpdateWorkspaceDormantAt: true,
|
||||
TimeTilDormantAutoDeleteMillis: ptr.Ref(dormantTTL.Milliseconds()),
|
||||
UpdateWorkspaceDormantAt: ptr.Ref(true),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, dormantTTL.Milliseconds(), updated.TimeTilDormantAutoDeleteMillis)
|
||||
@@ -661,8 +663,8 @@ func TestTemplates(t *testing.T) {
|
||||
|
||||
inactivityTTL := time.Minute
|
||||
updated, err := anotherClient.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{
|
||||
TimeTilDormantMillis: inactivityTTL.Milliseconds(),
|
||||
UpdateWorkspaceLastUsedAt: true,
|
||||
TimeTilDormantMillis: ptr.Ref(inactivityTTL.Milliseconds()),
|
||||
UpdateWorkspaceLastUsedAt: ptr.Ref(true),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, inactivityTTL.Milliseconds(), updated.TimeTilDormantMillis)
|
||||
@@ -706,14 +708,14 @@ func TestTemplates(t *testing.T) {
|
||||
|
||||
// Update the field and assert it persists.
|
||||
updatedTemplate, err := anotherClient.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{
|
||||
RequireActiveVersion: false,
|
||||
RequireActiveVersion: ptr.Ref(false),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.False(t, updatedTemplate.RequireActiveVersion)
|
||||
|
||||
// Flip it back to ensure we aren't hardcoding to a default value.
|
||||
updatedTemplate, err = anotherClient.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{
|
||||
RequireActiveVersion: true,
|
||||
RequireActiveVersion: ptr.Ref(true),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.True(t, updatedTemplate.RequireActiveVersion)
|
||||
@@ -1003,12 +1005,12 @@ func TestTemplateACL(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(acl.Groups))
|
||||
_, err = client.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{
|
||||
Name: template.Name,
|
||||
Name: ptr.Ref(template.Name),
|
||||
DisplayName: &template.DisplayName,
|
||||
Description: &template.Description,
|
||||
Icon: &template.Icon,
|
||||
AllowUserCancelWorkspaceJobs: template.AllowUserCancelWorkspaceJobs,
|
||||
DisableEveryoneGroupAccess: true,
|
||||
AllowUserCancelWorkspaceJobs: ptr.Ref(template.AllowUserCancelWorkspaceJobs),
|
||||
DisableEveryoneGroupAccess: ptr.Ref(true),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
|
||||
"github.com/coder/coder/v2/coderd/coderdtest"
|
||||
"github.com/coder/coder/v2/coderd/rbac"
|
||||
"github.com/coder/coder/v2/coderd/util/ptr"
|
||||
"github.com/coder/coder/v2/codersdk"
|
||||
"github.com/coder/coder/v2/enterprise/coderd/coderdenttest"
|
||||
"github.com/coder/coder/v2/enterprise/coderd/license"
|
||||
@@ -43,7 +44,7 @@ func TestWorkspaceBuild(t *testing.T) {
|
||||
coderdtest.AwaitTemplateVersionJobCompleted(t, ownerClient, tplAv1.ID)
|
||||
require.Equal(t, tplAv1.ID, tplA.ActiveVersionID)
|
||||
tplA = coderdtest.UpdateTemplateMeta(t, ownerClient, tplA.ID, codersdk.UpdateTemplateMeta{
|
||||
RequireActiveVersion: true,
|
||||
RequireActiveVersion: ptr.Ref(true),
|
||||
})
|
||||
require.True(t, tplA.RequireActiveVersion)
|
||||
tplAv2 := coderdtest.CreateTemplateVersion(t, ownerClient, owner.OrganizationID, nil, func(ctvr *codersdk.CreateTemplateVersionRequest) {
|
||||
@@ -57,7 +58,7 @@ func TestWorkspaceBuild(t *testing.T) {
|
||||
coderdtest.AwaitTemplateVersionJobCompleted(t, ownerClient, tplBv1.ID)
|
||||
require.Equal(t, tplBv1.ID, tplB.ActiveVersionID)
|
||||
tplB = coderdtest.UpdateTemplateMeta(t, ownerClient, tplB.ID, codersdk.UpdateTemplateMeta{
|
||||
RequireActiveVersion: true,
|
||||
RequireActiveVersion: ptr.Ref(true),
|
||||
})
|
||||
require.True(t, tplB.RequireActiveVersion)
|
||||
|
||||
|
||||
@@ -784,7 +784,7 @@ func TestWorkspaceAutobuild(t *testing.T) {
|
||||
}).Do().Template
|
||||
|
||||
template := coderdtest.UpdateTemplateMeta(t, client, tpl.ID, codersdk.UpdateTemplateMeta{
|
||||
TimeTilDormantMillis: inactiveTTL.Milliseconds(),
|
||||
TimeTilDormantMillis: ptr.Ref(inactiveTTL.Milliseconds()),
|
||||
})
|
||||
|
||||
resp := dbfake.WorkspaceBuild(t, db, database.WorkspaceTable{
|
||||
@@ -1260,7 +1260,7 @@ func TestWorkspaceAutobuild(t *testing.T) {
|
||||
require.Len(t, stats.Transitions, 0)
|
||||
|
||||
_, err = anotherClient.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{
|
||||
TimeTilDormantAutoDeleteMillis: dormantTTL.Milliseconds(),
|
||||
TimeTilDormantAutoDeleteMillis: ptr.Ref(dormantTTL.Milliseconds()),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -1334,7 +1334,7 @@ func TestWorkspaceAutobuild(t *testing.T) {
|
||||
// Now that we've validated that the workspace is eligible for autostart
|
||||
// lets cause it to become dormant.
|
||||
_, err = client.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{
|
||||
TimeTilDormantMillis: inactiveTTL.Milliseconds(),
|
||||
TimeTilDormantMillis: ptr.Ref(inactiveTTL.Milliseconds()),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -1433,7 +1433,7 @@ func TestWorkspaceAutobuild(t *testing.T) {
|
||||
|
||||
// Enable auto-deletion for the template.
|
||||
_, err = templateAdmin.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{
|
||||
TimeTilDormantAutoDeleteMillis: transitionTTL.Milliseconds(),
|
||||
TimeTilDormantAutoDeleteMillis: ptr.Ref(transitionTTL.Milliseconds()),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -1538,8 +1538,8 @@ func TestWorkspaceAutobuild(t *testing.T) {
|
||||
|
||||
// Update the template to require the promoted version.
|
||||
_, err = client.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{
|
||||
RequireActiveVersion: true,
|
||||
AllowUserAutostart: true,
|
||||
RequireActiveVersion: ptr.Ref(true),
|
||||
AllowUserAutostart: ptr.Ref(true),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -1832,7 +1832,7 @@ func TestTemplateDoesNotAllowUserAutostop(t *testing.T) {
|
||||
templateTTL = 72 * time.Hour.Milliseconds()
|
||||
ctx := testutil.Context(t, testutil.WaitShort)
|
||||
template = coderdtest.UpdateTemplateMeta(t, client, template.ID, codersdk.UpdateTemplateMeta{
|
||||
DefaultTTLMillis: templateTTL,
|
||||
DefaultTTLMillis: ptr.Ref(templateTTL),
|
||||
})
|
||||
workspace, err := client.Workspace(ctx, workspace.ID)
|
||||
require.NoError(t, err)
|
||||
@@ -4068,7 +4068,7 @@ func TestResolveAutostart(t *testing.T) {
|
||||
defer cancel()
|
||||
|
||||
_, err := ownerClient.UpdateTemplateMeta(ctx, version1.Template.ID, codersdk.UpdateTemplateMeta{
|
||||
RequireActiveVersion: true,
|
||||
RequireActiveVersion: ptr.Ref(true),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user