Skip to content

Commit 66234e7

Browse files
Merge branch 'main' into WAYP-3564-read-module-url
2 parents 4ec0bce + d64cb3c commit 66234e7

8 files changed

+339
-9
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
# Unreleased
2+
* Add support for HCP Terraform `/api/v2/workspaces/{external_id}/all-vars` API endpoint to fetch the list of all variables available to a workspace (include inherited variables from varsets) by @debrin-hc [#1105](https://github.com/hashicorp/go-tfe/pull/1105)
3+
4+
* Adds BETA support for listing `StackDeploymentGroups`, which is EXPERIMENTAL, SUBJECT TO CHANGE, and may not be available to all users by @hwatkins05-hashicorp [#1128](https://github.com/hashicorp/go-tfe/pull/1128)
25

36
# v1.82.0
47

helper_test.go

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2209,19 +2209,48 @@ func createTeamTokenWithOptions(t *testing.T, client *Client, tm *Team, options
22092209
}
22102210

22112211
func createVariable(t *testing.T, client *Client, w *Workspace) (*Variable, func()) {
2212+
options := VariableCreateOptions{
2213+
Key: String(randomString(t)),
2214+
Value: String(randomString(t)),
2215+
Category: Category(CategoryTerraform),
2216+
Description: String(randomString(t)),
2217+
}
2218+
return createVariableWithOptions(t, client, w, options)
2219+
}
2220+
2221+
func createVariableWithOptions(t *testing.T, client *Client, w *Workspace, options VariableCreateOptions) (*Variable, func()) {
22122222
var wCleanup func()
22132223

22142224
if w == nil {
22152225
w, wCleanup = createWorkspace(t, client, nil)
22162226
}
22172227

2228+
if options.Key == nil {
2229+
options.Key = String(randomString(t))
2230+
}
2231+
2232+
if options.Value == nil {
2233+
options.Value = String(randomString(t))
2234+
}
2235+
2236+
if options.Description == nil {
2237+
options.Description = String(randomString(t))
2238+
}
2239+
2240+
if options.Category == nil {
2241+
options.Category = Category(CategoryTerraform)
2242+
}
2243+
2244+
if options.HCL == nil {
2245+
options.HCL = Bool(false)
2246+
}
2247+
2248+
if options.Sensitive == nil {
2249+
options.Sensitive = Bool(false)
2250+
}
2251+
22182252
ctx := context.Background()
2219-
v, err := client.Variables.Create(ctx, w.ID, VariableCreateOptions{
2220-
Key: String(randomString(t)),
2221-
Value: String(randomString(t)),
2222-
Category: Category(CategoryTerraform),
2223-
Description: String(randomString(t)),
2224-
})
2253+
v, err := client.Variables.Create(ctx, w.ID, options)
22252254
if err != nil {
22262255
t.Fatal(err)
22272256
}

mocks/variable_mocks.go

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

stack_deployment_groups.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package tfe
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"net/url"
7+
)
8+
9+
// StackDeploymentGroups describes all the stack-deployment-groups related methods that the HCP Terraform API supports.
10+
type StackDeploymentGroups interface {
11+
// List returns a list of Deployment Groups in a stack.
12+
List(ctx context.Context, stackConfigID string, options *StackDeploymentGroupListOptions) (*StackDeploymentGroupList, error)
13+
}
14+
15+
type DeploymentGroupStatus string
16+
17+
const (
18+
DeploymentGroupStatusPending DeploymentGroupStatus = "pending"
19+
DeploymentGroupStatusDeploying DeploymentGroupStatus = "deploying"
20+
DeploymentGroupStatusSucceeded DeploymentGroupStatus = "succeeded"
21+
DeploymentGroupStatusFailed DeploymentGroupStatus = "failed"
22+
DeploymentGroupStatusAbandoned DeploymentGroupStatus = "abandoned"
23+
)
24+
25+
// stackDeploymentGroups implements StackDeploymentGroups.
26+
type stackDeploymentGroups struct {
27+
client *Client
28+
}
29+
30+
var _ StackDeploymentGroups = &stackDeploymentGroups{}
31+
32+
// StackDeploymentGroup represents a stack deployment group.
33+
type StackDeploymentGroup struct {
34+
ID string `jsonapi:"primary,stacks-deployment-groups"`
35+
Name string `jsonapi:"attr,name"`
36+
Status DeploymentGroupStatus `jsonapi:"attr,status"`
37+
CreatedAt string `jsonapi:"attr,created-at"`
38+
UpdatedAt string `jsonapi:"attr,updated-at"`
39+
40+
// Relationships
41+
StackConfiguration StackConfiguration `jsonapi:"relation,stack-configurations"`
42+
}
43+
44+
// StackDeploymentGroupList represents a list of stack deployment groups.
45+
type StackDeploymentGroupList struct {
46+
*Pagination
47+
Items []*StackDeploymentGroup
48+
}
49+
50+
// StackDeploymentGroupListOptions represents additional options when listing stack deployment groups.
51+
type StackDeploymentGroupListOptions struct {
52+
ListOptions
53+
}
54+
55+
// List returns a list of Deployment Groups in a stack, optionally filtered by additional parameters.
56+
func (s stackDeploymentGroups) List(ctx context.Context, stackConfigID string, options *StackDeploymentGroupListOptions) (*StackDeploymentGroupList, error) {
57+
if !validStringID(&stackConfigID) {
58+
return nil, fmt.Errorf("invalid stack configuration ID: %s", stackConfigID)
59+
}
60+
61+
if options == nil {
62+
options = &StackDeploymentGroupListOptions{}
63+
}
64+
65+
req, err := s.client.NewRequest("GET", fmt.Sprintf("stack-configurations/%s/stack-deployment-groups", url.PathEscape(stackConfigID)), options)
66+
if err != nil {
67+
return nil, err
68+
}
69+
70+
sdgl := &StackDeploymentGroupList{}
71+
err = req.Do(ctx, sdgl)
72+
if err != nil {
73+
return nil, err
74+
}
75+
76+
return sdgl, nil
77+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package tfe
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
"github.com/stretchr/testify/assert"
8+
"github.com/stretchr/testify/require"
9+
)
10+
11+
func TestStackDeploymentGroupsList(t *testing.T) {
12+
skipUnlessBeta(t)
13+
client := testClient(t)
14+
ctx := context.Background()
15+
16+
orgTest, orgTestCleanup := createOrganization(t, client)
17+
t.Cleanup(orgTestCleanup)
18+
19+
oauthClient, cleanup := createOAuthClient(t, client, orgTest, nil)
20+
t.Cleanup(cleanup)
21+
22+
stack, err := client.Stacks.Create(ctx, StackCreateOptions{
23+
Name: "test-stack",
24+
VCSRepo: &StackVCSRepoOptions{
25+
Identifier: "hashicorp-guides/pet-nulls-stack",
26+
OAuthTokenID: oauthClient.OAuthTokens[0].ID,
27+
},
28+
Project: &Project{
29+
ID: orgTest.DefaultProject.ID,
30+
},
31+
})
32+
33+
require.NoError(t, err)
34+
require.NotNil(t, stack)
35+
36+
stackUpdated, err := client.Stacks.UpdateConfiguration(ctx, stack.ID)
37+
require.NoError(t, err)
38+
require.NotNil(t, stackUpdated)
39+
require.NotEmpty(t, stackUpdated.LatestStackConfiguration.ID)
40+
41+
stackUpdated = pollStackDeployments(t, ctx, client, stackUpdated.ID)
42+
require.NotNil(t, stackUpdated.LatestStackConfiguration)
43+
44+
t.Run("List with valid stack configuration ID", func(t *testing.T) {
45+
sdgl, err := client.StackDeploymentGroups.List(ctx, stackUpdated.LatestStackConfiguration.ID, nil)
46+
require.NoError(t, err)
47+
require.NotNil(t, sdgl)
48+
for _, item := range sdgl.Items {
49+
assert.NotNil(t, item.ID)
50+
assert.NotEmpty(t, item.Name)
51+
assert.NotEmpty(t, item.Status)
52+
assert.NotNil(t, item.CreatedAt)
53+
assert.NotNil(t, item.UpdatedAt)
54+
}
55+
require.Len(t, sdgl.Items, 2)
56+
})
57+
58+
t.Run("List with invalid stack configuration ID", func(t *testing.T) {
59+
_, err := client.StackDeploymentGroups.List(ctx, "", nil)
60+
require.Error(t, err)
61+
})
62+
63+
t.Run("List with pagination", func(t *testing.T) {
64+
options := &StackDeploymentGroupListOptions{
65+
ListOptions: ListOptions{
66+
PageNumber: 1,
67+
PageSize: 1,
68+
},
69+
}
70+
sdgl, err := client.StackDeploymentGroups.List(ctx, stackUpdated.LatestStackConfiguration.ID, options)
71+
require.NoError(t, err)
72+
require.NotNil(t, sdgl)
73+
require.Len(t, sdgl.Items, 1)
74+
})
75+
}

tfe.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ type Client struct {
164164
Stacks Stacks
165165
StackConfigurations StackConfigurations
166166
StackDeployments StackDeployments
167+
StackDeploymentGroups StackDeploymentGroups
167168
StackPlans StackPlans
168169
StackPlanOperations StackPlanOperations
169170
StackSources StackSources
@@ -492,6 +493,7 @@ func NewClient(cfg *Config) (*Client, error) {
492493
client.Stacks = &stacks{client: client}
493494
client.StackConfigurations = &stackConfigurations{client: client}
494495
client.StackDeployments = &stackDeployments{client: client}
496+
client.StackDeploymentGroups = &stackDeploymentGroups{client: client}
495497
client.StackPlans = &stackPlans{client: client}
496498
client.StackPlanOperations = &stackPlanOperations{client: client}
497499
client.StackSources = &stackSources{client: client}

variable.go

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,12 @@ var _ Variables = (*variables)(nil)
1717
//
1818
// TFE API docs: https://developer.hashicorp.com/terraform/cloud-docs/api-docs/workspace-variables
1919
type Variables interface {
20-
// List all the variables associated with the given workspace.
20+
// List all the variables associated with the given workspace (doesn't include variables inherited from varsets).
2121
List(ctx context.Context, workspaceID string, options *VariableListOptions) (*VariableList, error)
2222

23+
// ListAll all the variables associated with the given workspace including variables inherited from varsets.
24+
ListAll(ctx context.Context, workspaceID string, options *VariableListOptions) (*VariableList, error)
25+
2326
// Create is used to create a new variable.
2427
Create(ctx context.Context, workspaceID string, options VariableCreateOptions) (*Variable, error)
2528

@@ -128,13 +131,22 @@ type VariableUpdateOptions struct {
128131
Sensitive *bool `jsonapi:"attr,sensitive,omitempty"`
129132
}
130133

131-
// List all the variables associated with the given workspace.
134+
// List all the variables associated with the given workspace (doesn't include variables inherited from varsets).
132135
func (s *variables) List(ctx context.Context, workspaceID string, options *VariableListOptions) (*VariableList, error) {
136+
return s.getList(ctx, workspaceID, options, "workspaces/%s/vars")
137+
}
138+
139+
// ListAll the variables associated with the given workspace including variables inherited from varsets.
140+
func (s *variables) ListAll(ctx context.Context, workspaceID string, options *VariableListOptions) (*VariableList, error) {
141+
return s.getList(ctx, workspaceID, options, "workspaces/%s/all-vars")
142+
}
143+
144+
func (s *variables) getList(ctx context.Context, workspaceID string, options *VariableListOptions, path string) (*VariableList, error) {
133145
if !validStringID(&workspaceID) {
134146
return nil, ErrInvalidWorkspaceID
135147
}
136148

137-
u := fmt.Sprintf("workspaces/%s/vars", url.PathEscape(workspaceID))
149+
u := fmt.Sprintf(path, url.PathEscape(workspaceID))
138150
req, err := s.client.NewRequest("GET", u, options)
139151
if err != nil {
140152
return nil, err

0 commit comments

Comments
 (0)