Skip to content

Commit e7fcc3c

Browse files
author
Miguel Hernández
committed
Merge branch 'main' into miguelhrocha/no-code-modules
2 parents e2592cd + af0a606 commit e7fcc3c

26 files changed

+1074
-139
lines changed

CHANGELOG.md

+13
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,20 @@
22

33
## Enhancements
44

5+
* Add OPA support to the Policy Set API's by @mrinalirao [#575](https://github.com/hashicorp/go-tfe/pull/575)
6+
7+
# v1.12.0
8+
9+
## Enhancements
10+
11+
* Add `search[wildcard-name]` to `WorkspaceListOptions` by @laurenolivia [#569](https://github.com/hashicorp/go-tfe/pull/569)
512
* Add `NotificationTriggerAssessmentCheckFailed` notification trigger type by @rexredinger [#549](https://github.com/hashicorp/go-tfe/pull/549)
13+
* Add `RemoteTFEVersion()` to the `Client` interface, which exposes the `X-TFE-Version` header set by a remote TFE instance by @sebasslash [#563](https://github.com/hashicorp/go-tfe/pull/563)
14+
* Validate the module version as a version instead of an ID [#409](https://github.com/hashicorp/go-tfe/pull/409)
15+
* Add `AllowForceDeleteWorkspaces` setting to `Organizations` by @JarrettSpiker [#539](https://github.com/hashicorp/go-tfe/pull/539)
16+
* Add `SafeDelete` and `SafeDeleteID` APIs to `Workspaces` by @JarrettSpiker [#539](https://github.com/hashicorp/go-tfe/pull/539)
17+
* Add `ForceExecute()` to `Runs` to allow force executing a run by @annawinkler [#570](https://github.com/hashicorp/go-tfe/pull/570)
18+
* Pre-plan and Pre-Apply Run Tasks are now generally available (beta comments removed) by @glennsarti [#555](https://github.com/hashicorp/go-tfe/pull/555)
619

720
# v1.11.0
821

configuration_version_integration_test.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,8 @@ func TestConfigurationVersionsArchive(t *testing.T) {
263263
// configuration version should not be archived, since it's the latest version
264264
err = client.ConfigurationVersions.Archive(ctx, cv.ID)
265265
assert.Error(t, err)
266-
assert.EqualError(t, err, "transition not allowed")
266+
assert.ErrorContains(t, err, "transition not allowed")
267+
assert.ErrorContains(t, err, "configuration could not be archived because it is current")
267268

268269
// create subsequent version, since the latest configuration version cannot be archived
269270
newCv, newCvCleanup := createConfigurationVersion(t, client, w)

docs/CONTRIBUTING.md

+23-10
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,10 @@ There are instances where several new resources being added (i.e Workspace Run T
2525

2626
The test suite contains many acceptance tests that are run against the latest version of Terraform Enterprise. You can read more about running the tests against your own Terraform Enterprise environment in [TESTS.md](TESTS.md). Our CI system (Github Actions) will not test your fork until a one-time approval takes place.
2727

28-
<<<<<<< HEAD
29-
<<<<<<< HEAD
30-
=======
3128
## Test Splitting
3229

3330
Our CI workflow makes use of multiple nodes to run our tests in a more efficient manner. To prevent your test from running across all nodes, you **must** add `skipIfNotCINode(t)` to your top level test before any other helper or test logic.
3431

35-
>>>>>>> e307d93 (rename from checktestnode to skipIfNotCINode)
36-
=======
37-
## Test Splitting
38-
39-
Our CI workflow makes use of multiple nodes to run our tests in a more efficient manner. To prevent your test from running across all nodes, you **must** add `checkTestNodeEnv(t)` to your top level test before any other helper or test logic.
40-
41-
>>>>>>> d0e4157 (Update contributing docs to mention test splitting)
4232
## Editor Settings
4333

4434
We've included VSCode settings to assist with configuring the go extension. For other editors that integrate with the [Go Language Server](https://github.com/golang/tools/tree/master/gopls), the main thing to do is to add the `integration` build tags so that the test files are found by the language server. See `.vscode/settings.json` for more details.
@@ -412,3 +402,26 @@ func validateExampleIncludeParams(params []ExampleIncludeOpt) error {
412402
return nil
413403
}
414404
```
405+
406+
## Rebasing a fork to trigger CI (Maintainers Only)
407+
408+
Pull requests that originate from a fork will not have access to this repository's secrets, thus resulting in the inability to test against our CI instance. In order to trigger the CI action workflow, there is a handy script `./scripts/rebase-fork.sh` that automates the steps for you. It will:
409+
410+
* Checkout the fork PR locally onto your machine and create a new branch prefixed as follows: `local/{name_of_fork_branch}`
411+
* Push your newly created branch to Github, appending an empty commit stating the original branch that was rebased.
412+
* Copy the contents of the fork's pull request (title and description) and create a new pull request, triggering the CI workflow.
413+
414+
**Important**: This script does not handle subsequent commits to the original PR and would require you to rebase them manually. Therefore, it is important that authors include test results in their description and changes are approved before this script is executed.
415+
416+
This script depends on `gh` and `jq`. It also requires you to `gh auth login`, providing a SSO-authorized personal access token with the following scopes enabled:
417+
418+
- repo
419+
- read:org
420+
- read:discussion
421+
422+
### Example Usage
423+
424+
```sh
425+
./scripts/rebase-fork.sh 557
426+
```
427+

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ require (
99
github.com/hashicorp/go-retryablehttp v0.7.1
1010
github.com/hashicorp/go-slug v0.10.0
1111
github.com/hashicorp/go-uuid v1.0.3
12+
github.com/hashicorp/go-version v1.6.0
1213
github.com/hashicorp/jsonapi v0.0.0-20210826224640-ee7dae0fb22d
1314
github.com/stretchr/testify v1.8.1
1415
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4

go.sum

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ github.com/hashicorp/go-slug v0.10.0 h1:mh4DDkBJTh9BuEjY/cv8PTo7k9OjT4PcW8PgZnJ4
1818
github.com/hashicorp/go-slug v0.10.0/go.mod h1:Ib+IWBYfEfJGI1ZyXMGNbu2BU+aa3Dzu41RKLH301v4=
1919
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
2020
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
21+
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
22+
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
2123
github.com/hashicorp/jsonapi v0.0.0-20210826224640-ee7dae0fb22d h1:9ARUJJ1VVynB176G1HCwleORqCaXm/Vx0uUi0dL26I0=
2224
github.com/hashicorp/jsonapi v0.0.0-20210826224640-ee7dae0fb22d/go.mod h1:Yog5+CPEM3c99L1CL2CFCYoSzgWm5vTU58idbRUaLik=
2325
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=

helper_test.go

+6-5
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,7 @@ func createPolicySetParameter(t *testing.T, client *Client, ps *PolicySet) (*Pol
499499
var psCleanup func()
500500

501501
if ps == nil {
502-
ps, psCleanup = createPolicySet(t, client, nil, nil, nil)
502+
ps, psCleanup = createPolicySet(t, client, nil, nil, nil, "")
503503
}
504504

505505
ctx := context.Background()
@@ -525,7 +525,7 @@ func createPolicySetParameter(t *testing.T, client *Client, ps *PolicySet) (*Pol
525525
}
526526
}
527527

528-
func createPolicySet(t *testing.T, client *Client, org *Organization, policies []*Policy, workspaces []*Workspace) (*PolicySet, func()) {
528+
func createPolicySet(t *testing.T, client *Client, org *Organization, policies []*Policy, workspaces []*Workspace, kind PolicyKind) (*PolicySet, func()) {
529529
var orgCleanup func()
530530

531531
if org == nil {
@@ -537,6 +537,7 @@ func createPolicySet(t *testing.T, client *Client, org *Organization, policies [
537537
Name: String(randomString(t)),
538538
Policies: policies,
539539
Workspaces: workspaces,
540+
Kind: kind,
540541
})
541542
if err != nil {
542543
t.Fatal(err)
@@ -559,7 +560,7 @@ func createPolicySetVersion(t *testing.T, client *Client, ps *PolicySet) (*Polic
559560
var psCleanup func()
560561

561562
if ps == nil {
562-
ps, psCleanup = createPolicySet(t, client, nil, nil, nil)
563+
ps, psCleanup = createPolicySet(t, client, nil, nil, nil, "")
563564
}
564565

565566
ctx := context.Background()
@@ -1598,10 +1599,10 @@ func createWorkspaceWithOptions(t *testing.T, client *Client, org *Organization,
15981599
}
15991600

16001601
return w, func() {
1601-
if err := client.Workspaces.Delete(ctx, org.Name, w.Name); err != nil {
1602+
if err := client.Workspaces.DeleteByID(ctx, w.ID); err != nil {
16021603
t.Errorf("Error destroying workspace! WARNING: Dangling resources\n"+
16031604
"may exist! The full error is shown below.\n\n"+
1604-
"Workspace: %s\nError: %s", w.Name, err)
1605+
"Workspace: %s\nError: %s", w.ID, err)
16051606
}
16061607

16071608
if orgCleanup != nil {

mocks/run_mocks.go

+14
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mocks/workspace_mocks.go

+28
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

organization.go

+9
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ type Organization struct {
7878
TrialExpiresAt time.Time `jsonapi:"attr,trial-expires-at,iso8601"`
7979
TwoFactorConformant bool `jsonapi:"attr,two-factor-conformant"`
8080
SendPassingStatusesForUntriggeredSpeculativePlans bool `jsonapi:"attr,send-passing-statuses-for-untriggered-speculative-plans"`
81+
// Note: This will be false for TFE versions older than v202211, where the setting was introduced.
82+
// On those TFE versions, safe delete does not exist, so ALL deletes will be force deletes.
83+
AllowForceDeleteWorkspaces bool `jsonapi:"attr,allow-force-delete-workspaces"`
8184
}
8285

8386
// Capacity represents the current run capacity of an organization.
@@ -166,6 +169,9 @@ type OrganizationCreateOptions struct {
166169

167170
// Optional: SendPassingStatusesForUntriggeredSpeculativePlans toggles behavior of untriggered speculative plans to send status updates to version control systems like GitHub.
168171
SendPassingStatusesForUntriggeredSpeculativePlans *bool `jsonapi:"attr,send-passing-statuses-for-untriggered-speculative-plans,omitempty"`
172+
173+
// Optional: AllowForceDeleteWorkspaces toggles behavior of allowing workspace admins to delete workspaces with resources under management.
174+
AllowForceDeleteWorkspaces *bool `jsonapi:"attr,allow-force-delete-workspaces,omitempty"`
169175
}
170176

171177
// OrganizationUpdateOptions represents the options for updating an organization.
@@ -202,6 +208,9 @@ type OrganizationUpdateOptions struct {
202208

203209
// SendPassingStatusesForUntriggeredSpeculativePlans toggles behavior of untriggered speculative plans to send status updates to version control systems like GitHub.
204210
SendPassingStatusesForUntriggeredSpeculativePlans *bool `jsonapi:"attr,send-passing-statuses-for-untriggered-speculative-plans,omitempty"`
211+
212+
// Optional: AllowForceDeleteWorkspaces toggles behavior of allowing workspace admins to delete workspaces with resources under management.
213+
AllowForceDeleteWorkspaces *bool `jsonapi:"attr,allow-force-delete-workspaces,omitempty"`
205214
}
206215

207216
// ReadRunQueueOptions represents the options for showing the queue.

organization_integration_test.go

+36
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,43 @@ func TestOrganizationsReadRunTasksEntitlement(t *testing.T) {
565565
assert.NotEmpty(t, entitlements.ID)
566566
assert.True(t, entitlements.RunTasks)
567567
})
568+
}
569+
570+
func TestOrganizationsAllowForceDeleteSetting(t *testing.T) {
571+
skipIfNotCINode(t)
568572

573+
client := testClient(t)
574+
ctx := context.Background()
575+
576+
t.Run("creates and updates allow force delete", func(t *testing.T) {
577+
options := OrganizationCreateOptions{
578+
Name: String(randomString(t)),
579+
Email: String(randomString(t) + "@tfe.local"),
580+
AllowForceDeleteWorkspaces: Bool(true),
581+
}
582+
583+
org, err := client.Organizations.Create(ctx, options)
584+
require.NoError(t, err)
585+
586+
t.Cleanup(func() {
587+
err := client.Organizations.Delete(ctx, org.Name)
588+
if err != nil {
589+
t.Errorf("error deleting organization (%s): %s", org.Name, err)
590+
}
591+
})
592+
593+
assert.Equal(t, *options.Name, org.Name)
594+
assert.Equal(t, *options.Email, org.Email)
595+
assert.True(t, org.AllowForceDeleteWorkspaces)
596+
597+
org, err = client.Organizations.Update(ctx, org.Name, OrganizationUpdateOptions{AllowForceDeleteWorkspaces: Bool(false)})
598+
require.NoError(t, err)
599+
assert.False(t, org.AllowForceDeleteWorkspaces)
600+
601+
org, err = client.Organizations.Read(ctx, org.Name)
602+
require.NoError(t, err)
603+
assert.False(t, org.AllowForceDeleteWorkspaces)
604+
})
569605
}
570606

571607
func orgItemsContainsName(items []*Organization, name string) bool {

policy_check_integration_test.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ func TestPolicyChecksList(t *testing.T) {
3131
defer policyCleanup2()
3232
wTest, wsCleanup := createWorkspace(t, client, orgTest)
3333
defer wsCleanup()
34-
createPolicySet(t, client, orgTest, []*Policy{pTest1, pTest2}, []*Workspace{wTest})
34+
createPolicySet(t, client, orgTest, []*Policy{pTest1, pTest2}, []*Workspace{wTest}, "")
3535

3636
rTest, runCleanup := createPolicyCheckedRun(t, client, wTest)
3737
defer runCleanup()
@@ -95,7 +95,7 @@ func TestPolicyChecksRead(t *testing.T) {
9595

9696
pTest, _ := createUploadedPolicy(t, client, true, orgTest)
9797
wTest, _ := createWorkspace(t, client, orgTest)
98-
createPolicySet(t, client, orgTest, []*Policy{pTest}, []*Workspace{wTest})
98+
createPolicySet(t, client, orgTest, []*Policy{pTest}, []*Workspace{wTest}, "")
9999

100100
rTest, _ := createPolicyCheckedRun(t, client, wTest)
101101
require.Equal(t, 1, len(rTest.PolicyChecks))
@@ -142,7 +142,7 @@ func TestPolicyChecksOverride(t *testing.T) {
142142

143143
wTest, wTestCleanup := createWorkspace(t, client, orgTest)
144144
defer wTestCleanup()
145-
createPolicySet(t, client, orgTest, []*Policy{pTest}, []*Workspace{wTest})
145+
createPolicySet(t, client, orgTest, []*Policy{pTest}, []*Workspace{wTest}, "")
146146
rTest, tTestCleanup := createPolicyCheckedRun(t, client, wTest)
147147
defer tTestCleanup()
148148

@@ -167,7 +167,7 @@ func TestPolicyChecksOverride(t *testing.T) {
167167

168168
wTest, wTestCleanup := createWorkspace(t, client, orgTest)
169169
defer wTestCleanup()
170-
createPolicySet(t, client, orgTest, []*Policy{pTest}, []*Workspace{wTest})
170+
createPolicySet(t, client, orgTest, []*Policy{pTest}, []*Workspace{wTest}, "")
171171
rTest, rTestCleanup := createPolicyCheckedRun(t, client, wTest)
172172
defer rTestCleanup()
173173

@@ -201,7 +201,7 @@ func TestPolicyChecksLogs(t *testing.T) {
201201
defer pTestCleanup()
202202
wTest, wTestCleanup := createWorkspace(t, client, orgTest)
203203
defer wTestCleanup()
204-
createPolicySet(t, client, orgTest, []*Policy{pTest}, []*Workspace{wTest})
204+
createPolicySet(t, client, orgTest, []*Policy{pTest}, []*Workspace{wTest}, "")
205205

206206
rTest, rTestCleanup := createPolicyCheckedRun(t, client, wTest)
207207
defer rTestCleanup()

policy_set.go

+33-10
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@ import (
1010
// Compile-time proof of interface implementation.
1111
var _ PolicySets = (*policySets)(nil)
1212

13+
// PolicyKind is an indicator of the underlying technology that the policy or policy set supports.
14+
// There are two kinds documented in the enum.
15+
type PolicyKind string
16+
17+
const (
18+
OPA PolicyKind = "opa"
19+
Sentinel PolicyKind = "sentinel"
20+
)
21+
1322
// PolicySets describes all the policy set related methods that the Terraform
1423
// Enterprise API supports.
1524
//
@@ -61,16 +70,18 @@ type PolicySetList struct {
6170

6271
// PolicySet represents a Terraform Enterprise policy set.
6372
type PolicySet struct {
64-
ID string `jsonapi:"primary,policy-sets"`
65-
Name string `jsonapi:"attr,name"`
66-
Description string `jsonapi:"attr,description"`
67-
Global bool `jsonapi:"attr,global"`
68-
PoliciesPath string `jsonapi:"attr,policies-path"`
69-
PolicyCount int `jsonapi:"attr,policy-count"`
70-
VCSRepo *VCSRepo `jsonapi:"attr,vcs-repo"`
71-
WorkspaceCount int `jsonapi:"attr,workspace-count"`
72-
CreatedAt time.Time `jsonapi:"attr,created-at,iso8601"`
73-
UpdatedAt time.Time `jsonapi:"attr,updated-at,iso8601"`
73+
ID string `jsonapi:"primary,policy-sets"`
74+
Name string `jsonapi:"attr,name"`
75+
Description string `jsonapi:"attr,description"`
76+
Kind PolicyKind `jsonapi:"attr,kind"`
77+
Overridable *bool `jsonapi:"attr,overridable"`
78+
Global bool `jsonapi:"attr,global"`
79+
PoliciesPath string `jsonapi:"attr,policies-path"`
80+
PolicyCount int `jsonapi:"attr,policy-count"`
81+
VCSRepo *VCSRepo `jsonapi:"attr,vcs-repo"`
82+
WorkspaceCount int `jsonapi:"attr,workspace-count"`
83+
CreatedAt time.Time `jsonapi:"attr,created-at,iso8601"`
84+
UpdatedAt time.Time `jsonapi:"attr,updated-at,iso8601"`
7485

7586
// Relations
7687
// The organization to which the policy set belongs to.
@@ -105,6 +116,10 @@ type PolicySetListOptions struct {
105116
// Optional: A search string (partial policy set name) used to filter the results.
106117
Search string `url:"search[name],omitempty"`
107118

119+
// **Note: This field is still in BETA and subject to change.**
120+
// Optional: A kind string used to filter the results by the policy set kind.
121+
Kind PolicyKind `url:"filter[kind],omitempty"`
122+
108123
// Optional: A list of relations to include. See available resources
109124
// https://www.terraform.io/cloud-docs/api-docs/policy-sets#available-related-resources
110125
Include []PolicySetIncludeOpt `url:"include,omitempty"`
@@ -136,6 +151,14 @@ type PolicySetCreateOptions struct {
136151
// Optional: Whether or not the policy set is global.
137152
Global *bool `jsonapi:"attr,global,omitempty"`
138153

154+
// **Note: This field is still in BETA and subject to change.**
155+
// Optional: The underlying technology that the policy set supports
156+
Kind PolicyKind `jsonapi:"attr,kind,omitempty"`
157+
158+
// **Note: This field is still in BETA and subject to change.**
159+
// Optional: Whether or not users can override this policy when it fails during a run. Only valid for OPA policies.
160+
Overridable *bool `jsonapi:"attr,overridable,omitempty"`
161+
139162
// Optional: The sub-path within the attached VCS repository to ingress. All
140163
// files and directories outside of this sub-path will be ignored.
141164
// This option may only be specified when a VCS repo is present.

0 commit comments

Comments
 (0)