Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add workspace auto destroy duration field #902

Merged
merged 1 commit into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# Unreleased
## Enhancements
* Adds the `AutoDestroyActivityDuration` field to `Workspace` by @notchairmk [#902](https://github.com/hashicorp/go-tfe/pull/902)

## Deprecations
* The `IsSiteAdmin` field on User has been deprecated. Use the `IsAdmin` field instead [#900](https://github.com/hashicorp/go-tfe/pull/900)


# v1.53.0

## Enhancements
Expand Down
85 changes: 47 additions & 38 deletions workspace.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,44 +155,45 @@ type LockedByChoice struct {

// Workspace represents a Terraform Enterprise workspace.
type Workspace struct {
ID string `jsonapi:"primary,workspaces"`
Actions *WorkspaceActions `jsonapi:"attr,actions"`
AllowDestroyPlan bool `jsonapi:"attr,allow-destroy-plan"`
AssessmentsEnabled bool `jsonapi:"attr,assessments-enabled"`
AutoApply bool `jsonapi:"attr,auto-apply"`
AutoApplyRunTrigger bool `jsonapi:"attr,auto-apply-run-trigger"`
AutoDestroyAt jsonapi.NullableAttr[time.Time] `jsonapi:"attr,auto-destroy-at,iso8601,omitempty"`
CanQueueDestroyPlan bool `jsonapi:"attr,can-queue-destroy-plan"`
CreatedAt time.Time `jsonapi:"attr,created-at,iso8601"`
Description string `jsonapi:"attr,description"`
Environment string `jsonapi:"attr,environment"`
ExecutionMode string `jsonapi:"attr,execution-mode"`
FileTriggersEnabled bool `jsonapi:"attr,file-triggers-enabled"`
GlobalRemoteState bool `jsonapi:"attr,global-remote-state"`
Locked bool `jsonapi:"attr,locked"`
MigrationEnvironment string `jsonapi:"attr,migration-environment"`
Name string `jsonapi:"attr,name"`
Operations bool `jsonapi:"attr,operations"`
Permissions *WorkspacePermissions `jsonapi:"attr,permissions"`
QueueAllRuns bool `jsonapi:"attr,queue-all-runs"`
SpeculativeEnabled bool `jsonapi:"attr,speculative-enabled"`
SourceName string `jsonapi:"attr,source-name"`
SourceURL string `jsonapi:"attr,source-url"`
StructuredRunOutputEnabled bool `jsonapi:"attr,structured-run-output-enabled"`
TerraformVersion string `jsonapi:"attr,terraform-version"`
TriggerPrefixes []string `jsonapi:"attr,trigger-prefixes"`
TriggerPatterns []string `jsonapi:"attr,trigger-patterns"`
VCSRepo *VCSRepo `jsonapi:"attr,vcs-repo"`
WorkingDirectory string `jsonapi:"attr,working-directory"`
UpdatedAt time.Time `jsonapi:"attr,updated-at,iso8601"`
ResourceCount int `jsonapi:"attr,resource-count"`
ApplyDurationAverage time.Duration `jsonapi:"attr,apply-duration-average"`
PlanDurationAverage time.Duration `jsonapi:"attr,plan-duration-average"`
PolicyCheckFailures int `jsonapi:"attr,policy-check-failures"`
RunFailures int `jsonapi:"attr,run-failures"`
RunsCount int `jsonapi:"attr,workspace-kpis-runs-count"`
TagNames []string `jsonapi:"attr,tag-names"`
SettingOverwrites *WorkspaceSettingOverwrites `jsonapi:"attr,setting-overwrites"`
ID string `jsonapi:"primary,workspaces"`
Actions *WorkspaceActions `jsonapi:"attr,actions"`
AllowDestroyPlan bool `jsonapi:"attr,allow-destroy-plan"`
AssessmentsEnabled bool `jsonapi:"attr,assessments-enabled"`
AutoApply bool `jsonapi:"attr,auto-apply"`
AutoApplyRunTrigger bool `jsonapi:"attr,auto-apply-run-trigger"`
AutoDestroyAt jsonapi.NullableAttr[time.Time] `jsonapi:"attr,auto-destroy-at,iso8601,omitempty"`
AutoDestroyActivityDuration jsonapi.NullableAttr[string] `jsonapi:"attr,auto-destroy-activity-duration,omitempty"`
CanQueueDestroyPlan bool `jsonapi:"attr,can-queue-destroy-plan"`
CreatedAt time.Time `jsonapi:"attr,created-at,iso8601"`
Description string `jsonapi:"attr,description"`
Environment string `jsonapi:"attr,environment"`
ExecutionMode string `jsonapi:"attr,execution-mode"`
FileTriggersEnabled bool `jsonapi:"attr,file-triggers-enabled"`
GlobalRemoteState bool `jsonapi:"attr,global-remote-state"`
Locked bool `jsonapi:"attr,locked"`
MigrationEnvironment string `jsonapi:"attr,migration-environment"`
Name string `jsonapi:"attr,name"`
Operations bool `jsonapi:"attr,operations"`
Permissions *WorkspacePermissions `jsonapi:"attr,permissions"`
QueueAllRuns bool `jsonapi:"attr,queue-all-runs"`
SpeculativeEnabled bool `jsonapi:"attr,speculative-enabled"`
SourceName string `jsonapi:"attr,source-name"`
SourceURL string `jsonapi:"attr,source-url"`
StructuredRunOutputEnabled bool `jsonapi:"attr,structured-run-output-enabled"`
TerraformVersion string `jsonapi:"attr,terraform-version"`
TriggerPrefixes []string `jsonapi:"attr,trigger-prefixes"`
TriggerPatterns []string `jsonapi:"attr,trigger-patterns"`
VCSRepo *VCSRepo `jsonapi:"attr,vcs-repo"`
WorkingDirectory string `jsonapi:"attr,working-directory"`
UpdatedAt time.Time `jsonapi:"attr,updated-at,iso8601"`
ResourceCount int `jsonapi:"attr,resource-count"`
ApplyDurationAverage time.Duration `jsonapi:"attr,apply-duration-average"`
PlanDurationAverage time.Duration `jsonapi:"attr,plan-duration-average"`
PolicyCheckFailures int `jsonapi:"attr,policy-check-failures"`
RunFailures int `jsonapi:"attr,run-failures"`
RunsCount int `jsonapi:"attr,workspace-kpis-runs-count"`
TagNames []string `jsonapi:"attr,tag-names"`
SettingOverwrites *WorkspaceSettingOverwrites `jsonapi:"attr,setting-overwrites"`

// Relations
AgentPool *AgentPool `jsonapi:"relation,agent-pool"`
Expand Down Expand Up @@ -363,6 +364,10 @@ type WorkspaceCreateOptions struct {
// Optional: The time after which an automatic destroy run will be queued
AutoDestroyAt jsonapi.NullableAttr[time.Time] `jsonapi:"attr,auto-destroy-at,iso8601,omitempty"`

// Optional: 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"`

// Optional: A description for the workspace.
Description *string `jsonapi:"attr,description,omitempty"`

Expand Down Expand Up @@ -513,6 +518,10 @@ type WorkspaceUpdateOptions struct {
// Optional: The time after which an automatic destroy run will be queued
AutoDestroyAt jsonapi.NullableAttr[time.Time] `jsonapi:"attr,auto-destroy-at,iso8601,omitempty"`

// Optional: 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"`

// 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
Expand Down
35 changes: 33 additions & 2 deletions workspace_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"time"

retryablehttp "github.com/hashicorp/go-retryablehttp"
"github.com/hashicorp/jsonapi"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -2747,7 +2748,7 @@ func TestWorkspacesAutoDestroy(t *testing.T) {
})
t.Cleanup(wCleanup)

require.Equal(t, wTest.AutoDestroyAt, autoDestroyAt)
require.Equal(t, autoDestroyAt, wTest.AutoDestroyAt)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

swapped the order on these since require wants require.Equal(t, <expected>, <actual>)


// respect default omitempty
w, err := client.Workspaces.Update(ctx, orgTest.Name, wTest.Name, WorkspaceUpdateOptions{
Expand All @@ -2764,7 +2765,7 @@ func TestWorkspacesAutoDestroy(t *testing.T) {

require.NoError(t, err)
require.NotNil(t, w.AutoDestroyAt)
require.NotEqual(t, w.AutoDestroyAt, autoDestroyAt)
require.NotEqual(t, autoDestroyAt, w.AutoDestroyAt)

// disable auto destroy
w, err = client.Workspaces.Update(ctx, orgTest.Name, wTest.Name, WorkspaceUpdateOptions{
Expand All @@ -2774,3 +2775,33 @@ func TestWorkspacesAutoDestroy(t *testing.T) {
require.NoError(t, err)
require.Nil(t, w.AutoDestroyAt)
}

func TestWorkspacesAutoDestroyDuration(t *testing.T) {
client := testClient(t)
ctx := context.Background()

orgTest, orgTestCleanup := createOrganization(t, client)
t.Cleanup(orgTestCleanup)

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.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())
}
Loading