From c0878ba380b27549bfb52c4139f23fcc1828b33a Mon Sep 17 00:00:00 2001 From: simonxmh Date: Mon, 25 Nov 2024 15:23:07 -0500 Subject: [PATCH 01/19] Add project level settings for auto destroy setting --- CHANGELOG.md | 2 ++ examples/projects/main.go | 55 ++++++++++++++++++++++++++++++++++++ project.go | 14 +++++++++ projects_integration_test.go | 53 ++++++++++++++++++++++++++++++++++ 4 files changed, 124 insertions(+) create mode 100644 examples/projects/main.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 40f233728..607c609c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # Unreleased +* Add support for project level auto destroy settings @simonxmh + ## Enhancements * Add support for listing effective tag bindings for a workspace or project by @brandonc diff --git a/examples/projects/main.go b/examples/projects/main.go new file mode 100644 index 000000000..049b32057 --- /dev/null +++ b/examples/projects/main.go @@ -0,0 +1,55 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package main + +import ( + "context" + "log" + + tfe "github.com/hashicorp/go-tfe" +) + +func main() { + config := &tfe.Config{ + Token: "insert-your-token-here", + RetryServerErrors: true, + } + + client, err := tfe.NewClient(config) + if err != nil { + log.Fatal(err) + } + + // Create a context + ctx := context.Background() + + // Create a new project + p, err := client.Projects.Create(ctx, "org-name", tfe.ProjectCreateOptions{ + Name: "my-app-tst", + }) + if err != nil { + log.Fatal(err) + } + + // Update the project auto destroy activity duration + p, err = client.Projects.Update(ctx, p.ID, tfe.ProjectUpdateOptions{ + AutoDestroyActivityDuration: tfe.String("3d"), + }) + if err != nil { + log.Fatal(err) + } + + // Disable auto destroy + p, err = client.Projects.Update(ctx, p.ID, tfe.ProjectUpdateOptions{ + AutoDestroyActivityDuration: tfe.String(""), + }) + if err != nil { + log.Fatal(err) + } + + err = client.Projects.Delete(ctx, p.ID) + if err != nil { + log.Fatal(err) + } +} diff --git a/project.go b/project.go index 89437a328..963ddb360 100644 --- a/project.go +++ b/project.go @@ -7,6 +7,8 @@ import ( "context" "fmt" "net/url" + + "github.com/hashicorp/jsonapi" ) // Compile-time proof of interface implementation. @@ -63,6 +65,8 @@ type Project struct { Description string `jsonapi:"attr,description"` + AutoDestroyActivityDuration jsonapi.NullableAttr[string] `jsonapi:"attr,auto-destroy-activity-duration,omitempty"` + // Relations Organization *Organization `jsonapi:"relation,organization"` } @@ -100,6 +104,11 @@ type ProjectCreateOptions struct { // Associated TagBindings of the project. TagBindings []*TagBinding `jsonapi:"relation,tag-bindings,omitempty"` + + // Optional: For all workspaces in the project, the period of time to wait + // after workspace activity to trigger a destroy run. The format should roughly + // match a Go duration string limited to days and hours, e.g. "24h" or "1d". + AutoDestroyActivityDuration jsonapi.NullableAttr[string] `jsonapi:"attr,auto-destroy-activity-duration,omitempty"` } // ProjectUpdateOptions represents the options for updating a project @@ -119,6 +128,11 @@ type ProjectUpdateOptions struct { // Associated TagBindings of the project. Note that this will replace // all existing tag bindings. TagBindings []*TagBinding `jsonapi:"relation,tag-bindings,omitempty"` + + // Optional: For all workspaces in the project, the period of time to wait + // after workspace activity to trigger a destroy run. The format should roughly + // match a Go duration string limited to days and hours, e.g. "24h" or "1d". + AutoDestroyActivityDuration jsonapi.NullableAttr[string] `jsonapi:"attr,auto-destroy-activity-duration,omitempty"` } // ProjectAddTagBindingsOptions represents the options for adding tag bindings diff --git a/projects_integration_test.go b/projects_integration_test.go index 962719282..eee9748cb 100644 --- a/projects_integration_test.go +++ b/projects_integration_test.go @@ -10,6 +10,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/hashicorp/jsonapi" ) func TestProjectsList(t *testing.T) { @@ -154,6 +156,7 @@ func TestProjectsCreate(t *testing.T) { options := ProjectCreateOptions{ Name: "foo", Description: String("qux"), + AutoDestroyActivityDuration: jsonapi.NewNullableAttrWithValue("3d"), } w, err := client.Projects.Create(ctx, orgTest.Name, options) @@ -169,6 +172,7 @@ func TestProjectsCreate(t *testing.T) { assert.NotEmpty(t, item.ID) assert.Equal(t, options.Name, item.Name) assert.Equal(t, *options.Description, item.Description) + assert.Equal(t, options.AutoDestroyActivityDuration, item.AutoDestroyActivityDuration) } }) @@ -193,6 +197,15 @@ func TestProjectsCreate(t *testing.T) { assert.Nil(t, w) assert.EqualError(t, err, ErrInvalidOrg.Error()) }) + + t.Run("when options has an invalid auto destroy activity duration", func(t *testing.T) { + w, err := client.Projects.Create(ctx, orgTest.Name, ProjectCreateOptions{ + Name: "foo", + AutoDestroyActivityDuration: jsonapi.NewNullableAttrWithValue("20m"), + }) + assert.Nil(t, w) + assert.Contains(t, err.Error(), "invalid attribute\n\nAuto destroy activity duration has an incorrect format, we expect up to 4 numeric digits and 1 unit ('d' or 'h')") + }) } func TestProjectsUpdate(t *testing.T) { @@ -212,12 +225,14 @@ func TestProjectsUpdate(t *testing.T) { TagBindings: []*TagBinding{ {Key: "foo", Value: "bar"}, }, + AutoDestroyActivityDuration: jsonapi.NewNullableAttrWithValue("3d"), }) require.NoError(t, err) assert.Equal(t, kBefore.ID, kAfter.ID) assert.NotEqual(t, kBefore.Name, kAfter.Name) assert.NotEqual(t, kBefore.Description, kAfter.Description) + assert.NotEqual(t, kBefore.AutoDestroyActivityDuration, kAfter.AutoDestroyActivityDuration) if betaFeaturesEnabled() { bindings, err := client.Projects.ListTagBindings(ctx, kAfter.ID) @@ -284,6 +299,17 @@ func TestProjectsUpdate(t *testing.T) { assert.Nil(t, w) assert.EqualError(t, err, ErrInvalidProjectID.Error()) }) + + t.Run("without a valid projects auto destroy activity duration", func(t *testing.T) { + kBefore, kTestCleanup := createProject(t, client, orgTest) + defer kTestCleanup() + + w, err := client.Projects.Update(ctx, kBefore.ID, ProjectUpdateOptions{ + AutoDestroyActivityDuration: jsonapi.NewNullableAttrWithValue("bar"), + }) + assert.Nil(t, w) + assert.Contains(t, err.Error(), "invalid attribute\n\nAuto destroy activity duration has an incorrect format, we expect up to 4 numeric digits and 1 unit ('d' or 'h')") + }) } func TestProjectsAddTagBindings(t *testing.T) { @@ -378,3 +404,30 @@ func TestProjectsDelete(t *testing.T) { assert.EqualError(t, err, ErrInvalidProjectID.Error()) }) } + +func TestProjectsAutoDestroySettings(t *testing.T) { + client := testClient(t) + ctx := context.Background() + + orgTest, orgTestCleanup := createOrganization(t, client) + defer orgTestCleanup() + + t.Run("when creating workspace in project with autodestroy", func(t *testing.T) { + options := ProjectCreateOptions{ + Name: "foo", + Description: String("qux"), + AutoDestroyActivityDuration: jsonapi.NewNullableAttrWithValue("3d"), + } + + p, err := client.Projects.Create(ctx, orgTest.Name, options) + require.NoError(t, err) + + w, _ := createWorkspaceWithOptions(t, client, orgTest, WorkspaceCreateOptions{ + Name: String(randomString(t)), + Project: p, + }) + + assert.Equal(t, p.AutoDestroyActivityDuration, w.AutoDestroyActivityDuration,) + }) +} + From d7edaef9d21fba250a281e2e853c0a4fb251fb72 Mon Sep 17 00:00:00 2001 From: simonxmh Date: Mon, 25 Nov 2024 15:23:20 -0500 Subject: [PATCH 02/19] Add missing example change --- examples/projects/main.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/examples/projects/main.go b/examples/projects/main.go index 049b32057..b952f1bb5 100644 --- a/examples/projects/main.go +++ b/examples/projects/main.go @@ -8,6 +8,8 @@ import ( "log" tfe "github.com/hashicorp/go-tfe" + + "github.com/hashicorp/jsonapi" ) func main() { @@ -25,7 +27,7 @@ func main() { ctx := context.Background() // Create a new project - p, err := client.Projects.Create(ctx, "org-name", tfe.ProjectCreateOptions{ + p, err := client.Projects.Create(ctx, "org-test", tfe.ProjectCreateOptions{ Name: "my-app-tst", }) if err != nil { @@ -34,7 +36,7 @@ func main() { // Update the project auto destroy activity duration p, err = client.Projects.Update(ctx, p.ID, tfe.ProjectUpdateOptions{ - AutoDestroyActivityDuration: tfe.String("3d"), + AutoDestroyActivityDuration: jsonapi.NewNullableAttrWithValue("3d"), }) if err != nil { log.Fatal(err) @@ -42,7 +44,7 @@ func main() { // Disable auto destroy p, err = client.Projects.Update(ctx, p.ID, tfe.ProjectUpdateOptions{ - AutoDestroyActivityDuration: tfe.String(""), + AutoDestroyActivityDuration: jsonapi.NewNullNullableAttr[string](), }) if err != nil { log.Fatal(err) From 7b2f4dffbfd24575969ce4179634cf38ccf6abd6 Mon Sep 17 00:00:00 2001 From: simonxmh Date: Mon, 25 Nov 2024 15:34:24 -0500 Subject: [PATCH 03/19] fix fmt --- projects_integration_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/projects_integration_test.go b/projects_integration_test.go index eee9748cb..ff7ae6c3e 100644 --- a/projects_integration_test.go +++ b/projects_integration_test.go @@ -156,7 +156,7 @@ func TestProjectsCreate(t *testing.T) { options := ProjectCreateOptions{ Name: "foo", Description: String("qux"), - AutoDestroyActivityDuration: jsonapi.NewNullableAttrWithValue("3d"), + AutoDestroyActivityDuration: jsonapi.NewNullableAttrWithValue("3d"), } w, err := client.Projects.Create(ctx, orgTest.Name, options) @@ -430,4 +430,3 @@ func TestProjectsAutoDestroySettings(t *testing.T) { assert.Equal(t, p.AutoDestroyActivityDuration, w.AutoDestroyActivityDuration,) }) } - From 92539168b75dabb5bdc3e5387311b94c4d94b772 Mon Sep 17 00:00:00 2001 From: simonxmh Date: Mon, 25 Nov 2024 15:35:06 -0500 Subject: [PATCH 04/19] Update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 607c609c9..2dc177126 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Unreleased -* Add support for project level auto destroy settings @simonxmh +* Add support for project level auto destroy settings @simonxmh [#1010](https://github.com/hashicorp/go-tfe/pull/1011) ## Enhancements From 63388e4898b0a26c01fce61850bf0f5efeae0475 Mon Sep 17 00:00:00 2001 From: simonxmh Date: Mon, 25 Nov 2024 15:35:35 -0500 Subject: [PATCH 05/19] Fix typo --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2dc177126..f0c6f5ed0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Unreleased -* Add support for project level auto destroy settings @simonxmh [#1010](https://github.com/hashicorp/go-tfe/pull/1011) +* Add support for project level auto destroy settings @simonxmh [#1011](https://github.com/hashicorp/go-tfe/pull/1011) ## Enhancements From d151e904441a1e5e3d1a41816bddf2522961fb14 Mon Sep 17 00:00:00 2001 From: simonxmh Date: Mon, 25 Nov 2024 15:42:43 -0500 Subject: [PATCH 06/19] Run go fmt --- project.go | 8 +++---- projects_integration_test.go | 44 ++++++++++++++++++------------------ 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/project.go b/project.go index 963ddb360..faf1da8c5 100644 --- a/project.go +++ b/project.go @@ -105,8 +105,8 @@ type ProjectCreateOptions struct { // Associated TagBindings of the project. TagBindings []*TagBinding `jsonapi:"relation,tag-bindings,omitempty"` - // Optional: For all workspaces in the project, the period of time to wait - // after workspace activity to trigger a destroy run. The format should roughly + // Optional: For all workspaces in the project, the period of time to wait + // after workspace activity to trigger a destroy run. The format should roughly // match a Go duration string limited to days and hours, e.g. "24h" or "1d". AutoDestroyActivityDuration jsonapi.NullableAttr[string] `jsonapi:"attr,auto-destroy-activity-duration,omitempty"` } @@ -129,8 +129,8 @@ type ProjectUpdateOptions struct { // all existing tag bindings. TagBindings []*TagBinding `jsonapi:"relation,tag-bindings,omitempty"` - // Optional: For all workspaces in the project, the period of time to wait - // after workspace activity to trigger a destroy run. The format should roughly + // Optional: For all workspaces in the project, the period of time to wait + // after workspace activity to trigger a destroy run. The format should roughly // match a Go duration string limited to days and hours, e.g. "24h" or "1d". AutoDestroyActivityDuration jsonapi.NullableAttr[string] `jsonapi:"attr,auto-destroy-activity-duration,omitempty"` } diff --git a/projects_integration_test.go b/projects_integration_test.go index ff7ae6c3e..a42d1c582 100644 --- a/projects_integration_test.go +++ b/projects_integration_test.go @@ -154,9 +154,9 @@ func TestProjectsCreate(t *testing.T) { t.Run("with valid options", func(t *testing.T) { options := ProjectCreateOptions{ - Name: "foo", - Description: String("qux"), - AutoDestroyActivityDuration: jsonapi.NewNullableAttrWithValue("3d"), + Name: "foo", + Description: String("qux"), + AutoDestroyActivityDuration: jsonapi.NewNullableAttrWithValue("3d"), } w, err := client.Projects.Create(ctx, orgTest.Name, options) @@ -198,9 +198,9 @@ func TestProjectsCreate(t *testing.T) { assert.EqualError(t, err, ErrInvalidOrg.Error()) }) - t.Run("when options has an invalid auto destroy activity duration", func(t *testing.T) { + t.Run("when options has an invalid auto destroy activity duration", func(t *testing.T) { w, err := client.Projects.Create(ctx, orgTest.Name, ProjectCreateOptions{ - Name: "foo", + Name: "foo", AutoDestroyActivityDuration: jsonapi.NewNullableAttrWithValue("20m"), }) assert.Nil(t, w) @@ -225,7 +225,7 @@ func TestProjectsUpdate(t *testing.T) { TagBindings: []*TagBinding{ {Key: "foo", Value: "bar"}, }, - AutoDestroyActivityDuration: jsonapi.NewNullableAttrWithValue("3d"), + AutoDestroyActivityDuration: jsonapi.NewNullableAttrWithValue("3d"), }) require.NoError(t, err) @@ -305,8 +305,8 @@ func TestProjectsUpdate(t *testing.T) { defer kTestCleanup() w, err := client.Projects.Update(ctx, kBefore.ID, ProjectUpdateOptions{ - AutoDestroyActivityDuration: jsonapi.NewNullableAttrWithValue("bar"), - }) + AutoDestroyActivityDuration: jsonapi.NewNullableAttrWithValue("bar"), + }) assert.Nil(t, w) assert.Contains(t, err.Error(), "invalid attribute\n\nAuto destroy activity duration has an incorrect format, we expect up to 4 numeric digits and 1 unit ('d' or 'h')") }) @@ -412,21 +412,21 @@ func TestProjectsAutoDestroySettings(t *testing.T) { orgTest, orgTestCleanup := createOrganization(t, client) defer orgTestCleanup() - t.Run("when creating workspace in project with autodestroy", func(t *testing.T) { - options := ProjectCreateOptions{ - Name: "foo", - Description: String("qux"), - AutoDestroyActivityDuration: jsonapi.NewNullableAttrWithValue("3d"), - } + t.Run("when creating workspace in project with autodestroy", func(t *testing.T) { + options := ProjectCreateOptions{ + Name: "foo", + Description: String("qux"), + AutoDestroyActivityDuration: jsonapi.NewNullableAttrWithValue("3d"), + } - p, err := client.Projects.Create(ctx, orgTest.Name, options) - require.NoError(t, err) + p, err := client.Projects.Create(ctx, orgTest.Name, options) + require.NoError(t, err) - w, _ := createWorkspaceWithOptions(t, client, orgTest, WorkspaceCreateOptions{ - Name: String(randomString(t)), - Project: p, - }) + w, _ := createWorkspaceWithOptions(t, client, orgTest, WorkspaceCreateOptions{ + Name: String(randomString(t)), + Project: p, + }) - assert.Equal(t, p.AutoDestroyActivityDuration, w.AutoDestroyActivityDuration,) - }) + assert.Equal(t, p.AutoDestroyActivityDuration, w.AutoDestroyActivityDuration) + }) } From 778d796267b511f6bf1c604d3711c8d70fc16480 Mon Sep 17 00:00:00 2001 From: simonxmh Date: Mon, 25 Nov 2024 16:09:17 -0500 Subject: [PATCH 07/19] Add project moving workspace scoped tests --- workspace_integration_test.go | 115 +++++++++++++++++++++++++++++----- 1 file changed, 101 insertions(+), 14 deletions(-) diff --git a/workspace_integration_test.go b/workspace_integration_test.go index 1505716a6..7fe4f0ed7 100644 --- a/workspace_integration_test.go +++ b/workspace_integration_test.go @@ -3007,23 +3007,110 @@ func TestWorkspacesAutoDestroyDuration(t *testing.T) { upgradeOrganizationSubscription(t, client, orgTest) - duration := jsonapi.NewNullableAttrWithValue("14d") - nilDuration := jsonapi.NewNullNullableAttr[string]() - nilAutoDestroy := jsonapi.NewNullNullableAttr[time.Time]() - wTest, wCleanup := createWorkspaceWithOptions(t, client, orgTest, WorkspaceCreateOptions{ - Name: String(randomString(t)), - AutoDestroyActivityDuration: duration, + t.Run("when creating a new workspace", func(t *testing.T) { + duration := jsonapi.NewNullableAttrWithValue("14d") + nilDuration := jsonapi.NewNullNullableAttr[string]() + nilAutoDestroy := jsonapi.NewNullNullableAttr[time.Time]() + wTest, wCleanup := createWorkspaceWithOptions(t, client, orgTest, WorkspaceCreateOptions{ + Name: String(randomString(t)), + AutoDestroyActivityDuration: duration, + }) + t.Cleanup(wCleanup) + + require.Equal(t, duration, wTest.AutoDestroyActivityDuration) + require.NotEqual(t, nilAutoDestroy, wTest.AutoDestroyAt) + + w, err := client.Workspaces.Update(ctx, orgTest.Name, wTest.Name, WorkspaceUpdateOptions{ + AutoDestroyActivityDuration: nilDuration, + }) + + require.NoError(t, err) + require.False(t, w.AutoDestroyActivityDuration.IsSpecified()) + require.False(t, w.AutoDestroyAt.IsSpecified()) }) - t.Cleanup(wCleanup) - require.Equal(t, duration, wTest.AutoDestroyActivityDuration) - require.NotEqual(t, nilAutoDestroy, wTest.AutoDestroyAt) + t.Run("when moving from project without auto destroy to project with auto destroy", func(t *testing.T) { + kAfter, kTestCleanup := createProjectWithOptions(t, client, orgTest, ProjectCreateOptions{ + Name: randomString(t), + AutoDestroyActivityDuration: jsonapi.NewNullableAttrWithValue("3d"), + }) + defer kTestCleanup() - w, err := client.Workspaces.Update(ctx, orgTest.Name, wTest.Name, WorkspaceUpdateOptions{ - AutoDestroyActivityDuration: nilDuration, + wBefore, wBeforeCleanup := createWorkspaceWithOptions(t, client, orgTest, WorkspaceCreateOptions{ + Name: String(randomString(t)), + Project: orgTest.DefaultProject, + }) + defer wBeforeCleanup() + + options := WorkspaceUpdateOptions{ + Name: String(wBefore.Name), + Project: kAfter, + } + + wAfter, err := client.Workspaces.Update(ctx, orgTest.Name, wBefore.Name, options) + require.NoError(t, err) + + assert.Equal(t, wAfter.Project.ID, kAfter.ID) + assert.Equal(t, wAfter.AutoDestroyActivityDuration, kAfter.AutoDestroyActivityDuration) }) - require.NoError(t, err) - require.False(t, w.AutoDestroyActivityDuration.IsSpecified()) - require.False(t, w.AutoDestroyAt.IsSpecified()) + t.Run("when moving from project with auto destroy to project without auto destroy", func(t *testing.T) { + kBefore, kTestCleanup := createProjectWithOptions(t, client, orgTest, ProjectCreateOptions{ + Name: randomString(t), + AutoDestroyActivityDuration: jsonapi.NewNullableAttrWithValue("3d"), + }) + defer kTestCleanup() + + wBefore, wBeforeCleanup := createWorkspaceWithOptions(t, client, orgTest, WorkspaceCreateOptions{ + Name: String(randomString(t)), + Project: kBefore, + }) + defer wBeforeCleanup() + + options := WorkspaceUpdateOptions{ + Name: String(wBefore.Name), + Project: orgTest.DefaultProject, + } + + assert.Equal(t, wBefore.AutoDestroyActivityDuration, kBefore.AutoDestroyActivityDuration) + + wAfter, err := client.Workspaces.Update(ctx, orgTest.Name, wBefore.Name, options) + require.NoError(t, err) + + assert.Equal(t, wAfter.Project.ID, orgTest.DefaultProject.ID) + require.False(t, wAfter.AutoDestroyActivityDuration.IsSpecified()) + }) + + t.Run("when moving from project with auto destroy to another project with auto destroy", func(t *testing.T) { + kBefore, kTestCleanup := createProjectWithOptions(t, client, orgTest, ProjectCreateOptions{ + Name: randomString(t), + AutoDestroyActivityDuration: jsonapi.NewNullableAttrWithValue("3d"), + }) + defer kTestCleanup() + + kAfter, kTestCleanup := createProjectWithOptions(t, client, orgTest, ProjectCreateOptions{ + Name: randomString(t), + AutoDestroyActivityDuration: jsonapi.NewNullableAttrWithValue("1h"), + }) + defer kTestCleanup() + + wBefore, wBeforeCleanup := createWorkspaceWithOptions(t, client, orgTest, WorkspaceCreateOptions{ + Name: String(randomString(t)), + Project: kBefore, + }) + defer wBeforeCleanup() + + options := WorkspaceUpdateOptions{ + Name: String(wBefore.Name), + Project: kAfter, + } + + assert.Equal(t, wBefore.AutoDestroyActivityDuration, kBefore.AutoDestroyActivityDuration) + + wAfter, err := client.Workspaces.Update(ctx, orgTest.Name, wBefore.Name, options) + require.NoError(t, err) + + assert.Equal(t, wAfter.Project.ID, kAfter.ID) + assert.Equal(t, wAfter.AutoDestroyActivityDuration, kAfter.AutoDestroyActivityDuration) + }) } From 1baab8973d3b28e4a028dc31a7d6ab757d3ba00b Mon Sep 17 00:00:00 2001 From: simonxmh Date: Mon, 25 Nov 2024 16:12:13 -0500 Subject: [PATCH 08/19] Run go fmt again --- projects_integration_test.go | 2 +- workspace_integration_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/projects_integration_test.go b/projects_integration_test.go index a42d1c582..eb4b93577 100644 --- a/projects_integration_test.go +++ b/projects_integration_test.go @@ -405,7 +405,7 @@ func TestProjectsDelete(t *testing.T) { }) } -func TestProjectsAutoDestroySettings(t *testing.T) { +func TestProjectsAutoDestroy(t *testing.T) { client := testClient(t) ctx := context.Background() diff --git a/workspace_integration_test.go b/workspace_integration_test.go index 7fe4f0ed7..da329a563 100644 --- a/workspace_integration_test.go +++ b/workspace_integration_test.go @@ -3078,7 +3078,7 @@ func TestWorkspacesAutoDestroyDuration(t *testing.T) { require.NoError(t, err) assert.Equal(t, wAfter.Project.ID, orgTest.DefaultProject.ID) - require.False(t, wAfter.AutoDestroyActivityDuration.IsSpecified()) + require.False(t, wAfter.AutoDestroyActivityDuration.IsSpecified()) }) t.Run("when moving from project with auto destroy to another project with auto destroy", func(t *testing.T) { From a786c00267873ed06a0acb55f6030af9149ec04e Mon Sep 17 00:00:00 2001 From: simonxmh Date: Mon, 25 Nov 2024 16:29:26 -0500 Subject: [PATCH 09/19] Fix potential subscription error --- projects_integration_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/projects_integration_test.go b/projects_integration_test.go index eb4b93577..6c0182db3 100644 --- a/projects_integration_test.go +++ b/projects_integration_test.go @@ -152,6 +152,8 @@ func TestProjectsCreate(t *testing.T) { orgTest, orgTestCleanup := createOrganization(t, client) defer orgTestCleanup() + upgradeOrganizationSubscription(t, client, orgTest) + t.Run("with valid options", func(t *testing.T) { options := ProjectCreateOptions{ Name: "foo", @@ -301,6 +303,8 @@ func TestProjectsUpdate(t *testing.T) { }) t.Run("without a valid projects auto destroy activity duration", func(t *testing.T) { + upgradeOrganizationSubscription(t, client, orgTest) + kBefore, kTestCleanup := createProject(t, client, orgTest) defer kTestCleanup() From ae23c1fca4f813c65bb4ea6c4c5bdb11716c4c6b Mon Sep 17 00:00:00 2001 From: simonxmh Date: Tue, 26 Nov 2024 10:09:31 -0500 Subject: [PATCH 10/19] Add workspace level indicator of project inheritance --- projects_integration_test.go | 4 ++-- workspace.go | 1 + workspace_integration_test.go | 43 +++++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/projects_integration_test.go b/projects_integration_test.go index 6c0182db3..7d44e5b34 100644 --- a/projects_integration_test.go +++ b/projects_integration_test.go @@ -152,7 +152,7 @@ func TestProjectsCreate(t *testing.T) { orgTest, orgTestCleanup := createOrganization(t, client) defer orgTestCleanup() - upgradeOrganizationSubscription(t, client, orgTest) + upgradeOrganizationSubscription(t, client, orgTest) t.Run("with valid options", func(t *testing.T) { options := ProjectCreateOptions{ @@ -303,7 +303,7 @@ func TestProjectsUpdate(t *testing.T) { }) t.Run("without a valid projects auto destroy activity duration", func(t *testing.T) { - upgradeOrganizationSubscription(t, client, orgTest) + upgradeOrganizationSubscription(t, client, orgTest) kBefore, kTestCleanup := createProject(t, client, orgTest) defer kTestCleanup() diff --git a/workspace.go b/workspace.go index 1a3990dbb..eb7804913 100644 --- a/workspace.go +++ b/workspace.go @@ -186,6 +186,7 @@ type Workspace struct { ExecutionMode string `jsonapi:"attr,execution-mode"` FileTriggersEnabled bool `jsonapi:"attr,file-triggers-enabled"` GlobalRemoteState bool `jsonapi:"attr,global-remote-state"` + InheritsProjectAutoDestroy bool `jsonapi:"attr,inherits-project-auto-destroy"` Locked bool `jsonapi:"attr,locked"` MigrationEnvironment string `jsonapi:"attr,migration-environment"` Name string `jsonapi:"attr,name"` diff --git a/workspace_integration_test.go b/workspace_integration_test.go index da329a563..04ee47fec 100644 --- a/workspace_integration_test.go +++ b/workspace_integration_test.go @@ -3018,6 +3018,7 @@ func TestWorkspacesAutoDestroyDuration(t *testing.T) { t.Cleanup(wCleanup) require.Equal(t, duration, wTest.AutoDestroyActivityDuration) + require.Equal(t, wTest.InheritsProjectAutoDestroy, true) require.NotEqual(t, nilAutoDestroy, wTest.AutoDestroyAt) w, err := client.Workspaces.Update(ctx, orgTest.Name, wTest.Name, WorkspaceUpdateOptions{ @@ -3042,6 +3043,8 @@ func TestWorkspacesAutoDestroyDuration(t *testing.T) { }) defer wBeforeCleanup() + assert.Equal(t, wBefore.InheritsProjectAutoDestroy, true) + options := WorkspaceUpdateOptions{ Name: String(wBefore.Name), Project: kAfter, @@ -3052,6 +3055,7 @@ func TestWorkspacesAutoDestroyDuration(t *testing.T) { assert.Equal(t, wAfter.Project.ID, kAfter.ID) assert.Equal(t, wAfter.AutoDestroyActivityDuration, kAfter.AutoDestroyActivityDuration) + assert.Equal(t, wAfter.InheritsProjectAutoDestroy, true) }) t.Run("when moving from project with auto destroy to project without auto destroy", func(t *testing.T) { @@ -3067,6 +3071,8 @@ func TestWorkspacesAutoDestroyDuration(t *testing.T) { }) defer wBeforeCleanup() + assert.Equal(t, wBefore.InheritsProjectAutoDestroy, true) + options := WorkspaceUpdateOptions{ Name: String(wBefore.Name), Project: orgTest.DefaultProject, @@ -3078,6 +3084,7 @@ func TestWorkspacesAutoDestroyDuration(t *testing.T) { require.NoError(t, err) assert.Equal(t, wAfter.Project.ID, orgTest.DefaultProject.ID) + assert.Equal(t, wAfter.InheritsProjectAutoDestroy, true) require.False(t, wAfter.AutoDestroyActivityDuration.IsSpecified()) }) @@ -3106,11 +3113,47 @@ func TestWorkspacesAutoDestroyDuration(t *testing.T) { } assert.Equal(t, wBefore.AutoDestroyActivityDuration, kBefore.AutoDestroyActivityDuration) + assert.Equal(t, wBefore.InheritsProjectAutoDestroy, true) wAfter, err := client.Workspaces.Update(ctx, orgTest.Name, wBefore.Name, options) require.NoError(t, err) assert.Equal(t, wAfter.Project.ID, kAfter.ID) + assert.Equal(t, wAfter.InheritsProjectAutoDestroy, true) assert.Equal(t, wAfter.AutoDestroyActivityDuration, kAfter.AutoDestroyActivityDuration) }) + + t.Run("when moving workspaces that do not inherit project level settings", func(t *testing.T) { + kBefore, kTestCleanup := createProjectWithOptions(t, client, orgTest, ProjectCreateOptions{ + Name: randomString(t), + }) + defer kTestCleanup() + + kAfter, kTestCleanup := createProjectWithOptions(t, client, orgTest, ProjectCreateOptions{ + Name: randomString(t), + AutoDestroyActivityDuration: jsonapi.NewNullableAttrWithValue("1h"), + }) + defer kTestCleanup() + + wBefore, wBeforeCleanup := createWorkspaceWithOptions(t, client, orgTest, WorkspaceCreateOptions{ + Name: String(randomString(t)), + Project: kBefore, + AutoDestroyActivityDuration: jsonapi.NewNullableAttrWithValue("10d"), + }) + defer wBeforeCleanup() + + assert.Equal(t, wBefore.InheritsProjectAutoDestroy, true) + + options := WorkspaceUpdateOptions{ + Name: String(wBefore.Name), + Project: kAfter, + } + + wAfter, err := client.Workspaces.Update(ctx, orgTest.Name, wBefore.Name, options) + require.NoError(t, err) + + assert.Equal(t, wAfter.Project.ID, kAfter.ID) + assert.Equal(t, wAfter.InheritsProjectAutoDestroy, false) + assert.Equal(t, wAfter.AutoDestroyActivityDuration, wBefore.AutoDestroyActivityDuration) + }) } From b74e67facbb6676c2cfbbaa0f9d99bdda327955b Mon Sep 17 00:00:00 2001 From: simonxmh Date: Tue, 26 Nov 2024 11:04:48 -0500 Subject: [PATCH 11/19] Add new subscription updater --- projects_integration_test.go | 6 ++++-- workspace_integration_test.go | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/projects_integration_test.go b/projects_integration_test.go index 7d44e5b34..79cebf5be 100644 --- a/projects_integration_test.go +++ b/projects_integration_test.go @@ -152,7 +152,7 @@ func TestProjectsCreate(t *testing.T) { orgTest, orgTestCleanup := createOrganization(t, client) defer orgTestCleanup() - upgradeOrganizationSubscription(t, client, orgTest) + newSubscriptionUpdater(orgTest).WithPlusEntitlementPlan().Update(t) t.Run("with valid options", func(t *testing.T) { options := ProjectCreateOptions{ @@ -303,7 +303,7 @@ func TestProjectsUpdate(t *testing.T) { }) t.Run("without a valid projects auto destroy activity duration", func(t *testing.T) { - upgradeOrganizationSubscription(t, client, orgTest) + newSubscriptionUpdater(orgTest).WithPlusEntitlementPlan().Update(t) kBefore, kTestCleanup := createProject(t, client, orgTest) defer kTestCleanup() @@ -416,6 +416,8 @@ func TestProjectsAutoDestroy(t *testing.T) { orgTest, orgTestCleanup := createOrganization(t, client) defer orgTestCleanup() + newSubscriptionUpdater(orgTest).WithPlusEntitlementPlan().Update(t) + t.Run("when creating workspace in project with autodestroy", func(t *testing.T) { options := ProjectCreateOptions{ Name: "foo", diff --git a/workspace_integration_test.go b/workspace_integration_test.go index 04ee47fec..cbfefc1ad 100644 --- a/workspace_integration_test.go +++ b/workspace_integration_test.go @@ -2961,7 +2961,7 @@ func TestWorkspacesAutoDestroy(t *testing.T) { orgTest, orgTestCleanup := createOrganization(t, client) t.Cleanup(orgTestCleanup) - upgradeOrganizationSubscription(t, client, orgTest) + newSubscriptionUpdater(orgTest).WithPlusEntitlementPlan().Update(t) autoDestroyAt := NullableTime(time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC)) wTest, wCleanup := createWorkspaceWithOptions(t, client, orgTest, WorkspaceCreateOptions{ @@ -3005,7 +3005,7 @@ func TestWorkspacesAutoDestroyDuration(t *testing.T) { orgTest, orgTestCleanup := createOrganization(t, client) t.Cleanup(orgTestCleanup) - upgradeOrganizationSubscription(t, client, orgTest) + newSubscriptionUpdater(orgTest).WithBusinessPlan().Update(t) t.Run("when creating a new workspace", func(t *testing.T) { duration := jsonapi.NewNullableAttrWithValue("14d") From 645a0da89276372738c1edfa1c90e047d95f31c3 Mon Sep 17 00:00:00 2001 From: simonxmh Date: Thu, 5 Dec 2024 13:20:36 -0500 Subject: [PATCH 12/19] Remove some moving tests that have dependent logic --- workspace_integration_test.go | 127 ---------------------------------- 1 file changed, 127 deletions(-) diff --git a/workspace_integration_test.go b/workspace_integration_test.go index cbfefc1ad..f7d528059 100644 --- a/workspace_integration_test.go +++ b/workspace_integration_test.go @@ -3029,131 +3029,4 @@ func TestWorkspacesAutoDestroyDuration(t *testing.T) { require.False(t, w.AutoDestroyActivityDuration.IsSpecified()) require.False(t, w.AutoDestroyAt.IsSpecified()) }) - - t.Run("when moving from project without auto destroy to project with auto destroy", func(t *testing.T) { - kAfter, kTestCleanup := createProjectWithOptions(t, client, orgTest, ProjectCreateOptions{ - Name: randomString(t), - AutoDestroyActivityDuration: jsonapi.NewNullableAttrWithValue("3d"), - }) - defer kTestCleanup() - - wBefore, wBeforeCleanup := createWorkspaceWithOptions(t, client, orgTest, WorkspaceCreateOptions{ - Name: String(randomString(t)), - Project: orgTest.DefaultProject, - }) - defer wBeforeCleanup() - - assert.Equal(t, wBefore.InheritsProjectAutoDestroy, true) - - options := WorkspaceUpdateOptions{ - Name: String(wBefore.Name), - Project: kAfter, - } - - wAfter, err := client.Workspaces.Update(ctx, orgTest.Name, wBefore.Name, options) - require.NoError(t, err) - - assert.Equal(t, wAfter.Project.ID, kAfter.ID) - assert.Equal(t, wAfter.AutoDestroyActivityDuration, kAfter.AutoDestroyActivityDuration) - assert.Equal(t, wAfter.InheritsProjectAutoDestroy, true) - }) - - t.Run("when moving from project with auto destroy to project without auto destroy", func(t *testing.T) { - kBefore, kTestCleanup := createProjectWithOptions(t, client, orgTest, ProjectCreateOptions{ - Name: randomString(t), - AutoDestroyActivityDuration: jsonapi.NewNullableAttrWithValue("3d"), - }) - defer kTestCleanup() - - wBefore, wBeforeCleanup := createWorkspaceWithOptions(t, client, orgTest, WorkspaceCreateOptions{ - Name: String(randomString(t)), - Project: kBefore, - }) - defer wBeforeCleanup() - - assert.Equal(t, wBefore.InheritsProjectAutoDestroy, true) - - options := WorkspaceUpdateOptions{ - Name: String(wBefore.Name), - Project: orgTest.DefaultProject, - } - - assert.Equal(t, wBefore.AutoDestroyActivityDuration, kBefore.AutoDestroyActivityDuration) - - wAfter, err := client.Workspaces.Update(ctx, orgTest.Name, wBefore.Name, options) - require.NoError(t, err) - - assert.Equal(t, wAfter.Project.ID, orgTest.DefaultProject.ID) - assert.Equal(t, wAfter.InheritsProjectAutoDestroy, true) - require.False(t, wAfter.AutoDestroyActivityDuration.IsSpecified()) - }) - - t.Run("when moving from project with auto destroy to another project with auto destroy", func(t *testing.T) { - kBefore, kTestCleanup := createProjectWithOptions(t, client, orgTest, ProjectCreateOptions{ - Name: randomString(t), - AutoDestroyActivityDuration: jsonapi.NewNullableAttrWithValue("3d"), - }) - defer kTestCleanup() - - kAfter, kTestCleanup := createProjectWithOptions(t, client, orgTest, ProjectCreateOptions{ - Name: randomString(t), - AutoDestroyActivityDuration: jsonapi.NewNullableAttrWithValue("1h"), - }) - defer kTestCleanup() - - wBefore, wBeforeCleanup := createWorkspaceWithOptions(t, client, orgTest, WorkspaceCreateOptions{ - Name: String(randomString(t)), - Project: kBefore, - }) - defer wBeforeCleanup() - - options := WorkspaceUpdateOptions{ - Name: String(wBefore.Name), - Project: kAfter, - } - - assert.Equal(t, wBefore.AutoDestroyActivityDuration, kBefore.AutoDestroyActivityDuration) - assert.Equal(t, wBefore.InheritsProjectAutoDestroy, true) - - wAfter, err := client.Workspaces.Update(ctx, orgTest.Name, wBefore.Name, options) - require.NoError(t, err) - - assert.Equal(t, wAfter.Project.ID, kAfter.ID) - assert.Equal(t, wAfter.InheritsProjectAutoDestroy, true) - assert.Equal(t, wAfter.AutoDestroyActivityDuration, kAfter.AutoDestroyActivityDuration) - }) - - t.Run("when moving workspaces that do not inherit project level settings", func(t *testing.T) { - kBefore, kTestCleanup := createProjectWithOptions(t, client, orgTest, ProjectCreateOptions{ - Name: randomString(t), - }) - defer kTestCleanup() - - kAfter, kTestCleanup := createProjectWithOptions(t, client, orgTest, ProjectCreateOptions{ - Name: randomString(t), - AutoDestroyActivityDuration: jsonapi.NewNullableAttrWithValue("1h"), - }) - defer kTestCleanup() - - wBefore, wBeforeCleanup := createWorkspaceWithOptions(t, client, orgTest, WorkspaceCreateOptions{ - Name: String(randomString(t)), - Project: kBefore, - AutoDestroyActivityDuration: jsonapi.NewNullableAttrWithValue("10d"), - }) - defer wBeforeCleanup() - - assert.Equal(t, wBefore.InheritsProjectAutoDestroy, true) - - options := WorkspaceUpdateOptions{ - Name: String(wBefore.Name), - Project: kAfter, - } - - wAfter, err := client.Workspaces.Update(ctx, orgTest.Name, wBefore.Name, options) - require.NoError(t, err) - - assert.Equal(t, wAfter.Project.ID, kAfter.ID) - assert.Equal(t, wAfter.InheritsProjectAutoDestroy, false) - assert.Equal(t, wAfter.AutoDestroyActivityDuration, wBefore.AutoDestroyActivityDuration) - }) } From 8b68b25ec48f13ae9f9283f8b35d95ae7fb40044 Mon Sep 17 00:00:00 2001 From: simonxmh Date: Mon, 16 Dec 2024 13:29:25 -0500 Subject: [PATCH 13/19] Update API for go-tfe --- projects_integration_test.go | 1 + workspace.go | 7 +++++++ workspace_integration_test.go | 7 +++++-- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/projects_integration_test.go b/projects_integration_test.go index 79cebf5be..727ac06d0 100644 --- a/projects_integration_test.go +++ b/projects_integration_test.go @@ -235,6 +235,7 @@ func TestProjectsUpdate(t *testing.T) { assert.NotEqual(t, kBefore.Name, kAfter.Name) assert.NotEqual(t, kBefore.Description, kAfter.Description) assert.NotEqual(t, kBefore.AutoDestroyActivityDuration, kAfter.AutoDestroyActivityDuration) + assert.Equal(t, kAfter.AutoDestroyActivityDuration, jsonapi.NewNullableAttrWithValue("3d")) if betaFeaturesEnabled() { bindings, err := client.Projects.ListTagBindings(ctx, kAfter.ID) diff --git a/workspace.go b/workspace.go index eb7804913..141c4c871 100644 --- a/workspace.go +++ b/workspace.go @@ -394,6 +394,9 @@ type WorkspaceCreateOptions struct { // should roughly match a Go duration string limited to days and hours, e.g. "24h" or "1d". AutoDestroyActivityDuration jsonapi.NullableAttr[string] `jsonapi:"attr,auto-destroy-activity-duration,omitempty"` + // Optional: Whether the workspace inherits auto destroy settings from the project + InheritsProjectAutoDestroy *bool `jsonapi:"attr,inherits-project-auto-destroy,omitempty"` + // Optional: A description for the workspace. Description *string `jsonapi:"attr,description,omitempty"` @@ -551,6 +554,10 @@ type WorkspaceUpdateOptions struct { // should roughly match a Go duration string limited to days and hours, e.g. "24h" or "1d". AutoDestroyActivityDuration jsonapi.NullableAttr[string] `jsonapi:"attr,auto-destroy-activity-duration,omitempty"` + // Optional: Whether the workspace inherits auto destroy settings from the project + InheritsProjectAutoDestroy *bool `jsonapi:"attr,inherits-project-auto-destroy,omitempty"` + + // Optional: A new name for the workspace, which can only include letters, numbers, -, // and _. This will be used as an identifier and must be unique in the // organization. Warning: Changing a workspace's name changes its URL in the diff --git a/workspace_integration_test.go b/workspace_integration_test.go index f7d528059..7252e6509 100644 --- a/workspace_integration_test.go +++ b/workspace_integration_test.go @@ -3007,26 +3007,29 @@ func TestWorkspacesAutoDestroyDuration(t *testing.T) { newSubscriptionUpdater(orgTest).WithBusinessPlan().Update(t) - t.Run("when creating a new workspace", func(t *testing.T) { + t.Run("when creating a new workspace with standalone auto destroy settings", func(t *testing.T) { duration := jsonapi.NewNullableAttrWithValue("14d") nilDuration := jsonapi.NewNullNullableAttr[string]() nilAutoDestroy := jsonapi.NewNullNullableAttr[time.Time]() wTest, wCleanup := createWorkspaceWithOptions(t, client, orgTest, WorkspaceCreateOptions{ Name: String(randomString(t)), AutoDestroyActivityDuration: duration, + InheritsProjectAutoDestroy: Bool(false), }) t.Cleanup(wCleanup) require.Equal(t, duration, wTest.AutoDestroyActivityDuration) - require.Equal(t, wTest.InheritsProjectAutoDestroy, true) require.NotEqual(t, nilAutoDestroy, wTest.AutoDestroyAt) + require.Equal(t, wTest.InheritsProjectAutoDestroy, false) w, err := client.Workspaces.Update(ctx, orgTest.Name, wTest.Name, WorkspaceUpdateOptions{ AutoDestroyActivityDuration: nilDuration, + InheritsProjectAutoDestroy: Bool(false), }) require.NoError(t, err) require.False(t, w.AutoDestroyActivityDuration.IsSpecified()) require.False(t, w.AutoDestroyAt.IsSpecified()) + require.Equal(t, wTest.InheritsProjectAutoDestroy, false) }) } From c6b6f0457c372927c5ab2708c8b08c7551ef2ba6 Mon Sep 17 00:00:00 2001 From: simonxmh Date: Mon, 16 Dec 2024 13:33:43 -0500 Subject: [PATCH 14/19] Add fmt changes --- workspace.go | 1 - 1 file changed, 1 deletion(-) diff --git a/workspace.go b/workspace.go index 141c4c871..40ee48d71 100644 --- a/workspace.go +++ b/workspace.go @@ -557,7 +557,6 @@ type WorkspaceUpdateOptions struct { // Optional: Whether the workspace inherits auto destroy settings from the project InheritsProjectAutoDestroy *bool `jsonapi:"attr,inherits-project-auto-destroy,omitempty"` - // Optional: A new name for the workspace, which can only include letters, numbers, -, // and _. This will be used as an identifier and must be unique in the // organization. Warning: Changing a workspace's name changes its URL in the From a61d480b7d2cd8d9e462a77d9799f05317376974 Mon Sep 17 00:00:00 2001 From: simonxmh Date: Tue, 17 Dec 2024 12:59:22 -0500 Subject: [PATCH 15/19] update the main example --- examples/workspaces/main.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/examples/workspaces/main.go b/examples/workspaces/main.go index 5d460acac..b324e1dba 100644 --- a/examples/workspaces/main.go +++ b/examples/workspaces/main.go @@ -27,8 +27,9 @@ func main() { // Create a new workspace w, err := client.Workspaces.Create(ctx, "org-name", tfe.WorkspaceCreateOptions{ - Name: tfe.String("my-app-tst"), - AutoDestroyAt: tfe.NullableTime(time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC)), + Name: tfe.String("my-app-tst"), + AutoDestroyAt: tfe.NullableTime(time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC)), + InheritsProjectAutoDestroy: tfe.Bool(false), }) if err != nil { log.Fatal(err) @@ -36,10 +37,11 @@ func main() { // Update the workspace w, err = client.Workspaces.Update(ctx, "org-name", w.Name, tfe.WorkspaceUpdateOptions{ - AutoApply: tfe.Bool(false), - TerraformVersion: tfe.String("0.11.1"), - WorkingDirectory: tfe.String("my-app/infra"), - AutoDestroyAt: tfe.NullableTime(time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC)), + AutoApply: tfe.Bool(false), + TerraformVersion: tfe.String("0.11.1"), + WorkingDirectory: tfe.String("my-app/infra"), + AutoDestroyAt: tfe.NullableTime(time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC)), + InheritsProjectAutoDestroy: tfe.Bool(false), }) if err != nil { log.Fatal(err) From 35686c4a359bdda4207be025842be93fc301d07b Mon Sep 17 00:00:00 2001 From: simonxmh Date: Tue, 17 Dec 2024 15:55:49 -0500 Subject: [PATCH 16/19] Update all to use business plan --- projects_integration_test.go | 9 +++------ workspace_integration_test.go | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/projects_integration_test.go b/projects_integration_test.go index 727ac06d0..0219fe3ce 100644 --- a/projects_integration_test.go +++ b/projects_integration_test.go @@ -152,7 +152,7 @@ func TestProjectsCreate(t *testing.T) { orgTest, orgTestCleanup := createOrganization(t, client) defer orgTestCleanup() - newSubscriptionUpdater(orgTest).WithPlusEntitlementPlan().Update(t) + newSubscriptionUpdater(orgTest).WithBusinessPlan().Update(t) t.Run("with valid options", func(t *testing.T) { options := ProjectCreateOptions{ @@ -227,15 +227,12 @@ func TestProjectsUpdate(t *testing.T) { TagBindings: []*TagBinding{ {Key: "foo", Value: "bar"}, }, - AutoDestroyActivityDuration: jsonapi.NewNullableAttrWithValue("3d"), }) require.NoError(t, err) assert.Equal(t, kBefore.ID, kAfter.ID) assert.NotEqual(t, kBefore.Name, kAfter.Name) assert.NotEqual(t, kBefore.Description, kAfter.Description) - assert.NotEqual(t, kBefore.AutoDestroyActivityDuration, kAfter.AutoDestroyActivityDuration) - assert.Equal(t, kAfter.AutoDestroyActivityDuration, jsonapi.NewNullableAttrWithValue("3d")) if betaFeaturesEnabled() { bindings, err := client.Projects.ListTagBindings(ctx, kAfter.ID) @@ -304,7 +301,7 @@ func TestProjectsUpdate(t *testing.T) { }) t.Run("without a valid projects auto destroy activity duration", func(t *testing.T) { - newSubscriptionUpdater(orgTest).WithPlusEntitlementPlan().Update(t) + newSubscriptionUpdater(orgTest).WithBusinessPlan().Update(t) kBefore, kTestCleanup := createProject(t, client, orgTest) defer kTestCleanup() @@ -417,7 +414,7 @@ func TestProjectsAutoDestroy(t *testing.T) { orgTest, orgTestCleanup := createOrganization(t, client) defer orgTestCleanup() - newSubscriptionUpdater(orgTest).WithPlusEntitlementPlan().Update(t) + newSubscriptionUpdater(orgTest).WithBusinessPlan().Update(t) t.Run("when creating workspace in project with autodestroy", func(t *testing.T) { options := ProjectCreateOptions{ diff --git a/workspace_integration_test.go b/workspace_integration_test.go index 7252e6509..56f2eba4f 100644 --- a/workspace_integration_test.go +++ b/workspace_integration_test.go @@ -2961,7 +2961,7 @@ func TestWorkspacesAutoDestroy(t *testing.T) { orgTest, orgTestCleanup := createOrganization(t, client) t.Cleanup(orgTestCleanup) - newSubscriptionUpdater(orgTest).WithPlusEntitlementPlan().Update(t) + newSubscriptionUpdater(orgTest).WithBusinessPlan().Update(t) autoDestroyAt := NullableTime(time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC)) wTest, wCleanup := createWorkspaceWithOptions(t, client, orgTest, WorkspaceCreateOptions{ From 349d4fbd02e57b129b535038e82f5b24729017ae Mon Sep 17 00:00:00 2001 From: simonxmh Date: Tue, 17 Dec 2024 16:09:11 -0500 Subject: [PATCH 17/19] Add skip unless beta tags to certain tests --- projects_integration_test.go | 7 +++++-- workspace_integration_test.go | 4 +++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/projects_integration_test.go b/projects_integration_test.go index 0219fe3ce..ca7d06109 100644 --- a/projects_integration_test.go +++ b/projects_integration_test.go @@ -158,7 +158,6 @@ func TestProjectsCreate(t *testing.T) { options := ProjectCreateOptions{ Name: "foo", Description: String("qux"), - AutoDestroyActivityDuration: jsonapi.NewNullableAttrWithValue("3d"), } w, err := client.Projects.Create(ctx, orgTest.Name, options) @@ -174,7 +173,6 @@ func TestProjectsCreate(t *testing.T) { assert.NotEmpty(t, item.ID) assert.Equal(t, options.Name, item.Name) assert.Equal(t, *options.Description, item.Description) - assert.Equal(t, options.AutoDestroyActivityDuration, item.AutoDestroyActivityDuration) } }) @@ -201,6 +199,8 @@ func TestProjectsCreate(t *testing.T) { }) t.Run("when options has an invalid auto destroy activity duration", func(t *testing.T) { + skipUnlessBeta(t) + w, err := client.Projects.Create(ctx, orgTest.Name, ProjectCreateOptions{ Name: "foo", AutoDestroyActivityDuration: jsonapi.NewNullableAttrWithValue("20m"), @@ -301,6 +301,8 @@ func TestProjectsUpdate(t *testing.T) { }) t.Run("without a valid projects auto destroy activity duration", func(t *testing.T) { + skipUnlessBeta(t) + newSubscriptionUpdater(orgTest).WithBusinessPlan().Update(t) kBefore, kTestCleanup := createProject(t, client, orgTest) @@ -408,6 +410,7 @@ func TestProjectsDelete(t *testing.T) { } func TestProjectsAutoDestroy(t *testing.T) { + skipUnlessBeta(t) client := testClient(t) ctx := context.Background() diff --git a/workspace_integration_test.go b/workspace_integration_test.go index 56f2eba4f..67660acfe 100644 --- a/workspace_integration_test.go +++ b/workspace_integration_test.go @@ -2999,6 +2999,8 @@ func TestWorkspacesAutoDestroy(t *testing.T) { } func TestWorkspacesAutoDestroyDuration(t *testing.T) { + skipUnlessBeta(t) + client := testClient(t) ctx := context.Background() @@ -3007,7 +3009,7 @@ func TestWorkspacesAutoDestroyDuration(t *testing.T) { newSubscriptionUpdater(orgTest).WithBusinessPlan().Update(t) - t.Run("when creating a new workspace with standalone auto destroy settings", func(t *testing.T) { + t.Run("when creating a new workspace with standalone auto destroy settings", func(t *testing.T) { duration := jsonapi.NewNullableAttrWithValue("14d") nilDuration := jsonapi.NewNullNullableAttr[string]() nilAutoDestroy := jsonapi.NewNullNullableAttr[time.Time]() From a74077fd3646e11c24a8bebd8b2dcc3c39743a7a Mon Sep 17 00:00:00 2001 From: simonxmh Date: Tue, 17 Dec 2024 16:09:46 -0500 Subject: [PATCH 18/19] Run fmt --- projects_integration_test.go | 6 +++--- workspace_integration_test.go | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/projects_integration_test.go b/projects_integration_test.go index ca7d06109..b643aad9e 100644 --- a/projects_integration_test.go +++ b/projects_integration_test.go @@ -156,8 +156,8 @@ func TestProjectsCreate(t *testing.T) { t.Run("with valid options", func(t *testing.T) { options := ProjectCreateOptions{ - Name: "foo", - Description: String("qux"), + Name: "foo", + Description: String("qux"), } w, err := client.Projects.Create(ctx, orgTest.Name, options) @@ -302,7 +302,7 @@ func TestProjectsUpdate(t *testing.T) { t.Run("without a valid projects auto destroy activity duration", func(t *testing.T) { skipUnlessBeta(t) - + newSubscriptionUpdater(orgTest).WithBusinessPlan().Update(t) kBefore, kTestCleanup := createProject(t, client, orgTest) diff --git a/workspace_integration_test.go b/workspace_integration_test.go index 67660acfe..28e34c61c 100644 --- a/workspace_integration_test.go +++ b/workspace_integration_test.go @@ -3000,7 +3000,7 @@ func TestWorkspacesAutoDestroy(t *testing.T) { func TestWorkspacesAutoDestroyDuration(t *testing.T) { skipUnlessBeta(t) - + client := testClient(t) ctx := context.Background() @@ -3009,7 +3009,7 @@ func TestWorkspacesAutoDestroyDuration(t *testing.T) { newSubscriptionUpdater(orgTest).WithBusinessPlan().Update(t) - t.Run("when creating a new workspace with standalone auto destroy settings", func(t *testing.T) { + t.Run("when creating a new workspace with standalone auto destroy settings", func(t *testing.T) { duration := jsonapi.NewNullableAttrWithValue("14d") nilDuration := jsonapi.NewNullNullableAttr[string]() nilAutoDestroy := jsonapi.NewNullNullableAttr[time.Time]() From 5ad16613151b3f614a60fbaae10c5e24a32952c3 Mon Sep 17 00:00:00 2001 From: Simon Huang Date: Thu, 19 Dec 2024 08:50:12 -0800 Subject: [PATCH 19/19] Update CHANGELOG.md Co-authored-by: Sebastian Rivera --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ea311df0..0c5d6f95d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Unreleased +## Enhancements * Add support for project level auto destroy settings @simonxmh [#1011](https://github.com/hashicorp/go-tfe/pull/1011) # v1.71.0