Skip to content

Commit 494e8df

Browse files
authored
Merge pull request #682 from hashicorp/hs26gill/TF-3175-add-scoping-agent-pools-to-workspaces
Update for creating and filtering workspace scoped agent pools
2 parents a7c8535 + 93aa2cb commit 494e8df

5 files changed

+114
-3
lines changed

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@
44
* `ApplyToProjects` and `RemoveFromProjects` to `VariableSets` endpoints now generally available.
55
* `ListForProject` to `VariableSets` endpoints now generally available.
66

7+
## Enhancements
8+
* Adds `OrganizationScoped` and `AllowedWorkspaces` fields for creating workspace scoped agent pools and adds `AllowedWorkspacesName` for filtering agents pools associated with a given workspace by @hs26gill [#682](https://github.com/hashicorp/go-tfe/pull/682/files)
9+
10+
## Bug Fixes
11+
12+
713
# v1.22.0
814

915
## Beta API Changes

agent_pool.go

+10-1
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ type AgentPoolListOptions struct {
7979

8080
// Optional: A search query string used to filter agent pool. Agent pools are searchable by name
8181
Query string `url:"q,omitempty"`
82+
83+
// Optional: String (workspace name) used to filter the results.
84+
AllowedWorkspacesName string `url:"filter[allowed_workspaces][name],omitempty"`
8285
}
8386

8487
// AgentPoolCreateOptions represents the options for creating an agent pool.
@@ -91,6 +94,12 @@ type AgentPoolCreateOptions struct {
9194

9295
// Required: A name to identify the agent pool.
9396
Name *string `jsonapi:"attr,name"`
97+
98+
// True if the agent pool is organization scoped, false otherwise.
99+
OrganizationScoped *bool `jsonapi:"attr,organization-scoped,omitempty"`
100+
101+
// List of workspaces that are associated with an agent pool.
102+
AllowedWorkspaces []*Workspace `jsonapi:"relation,allowed-workspaces,omitempty"`
94103
}
95104

96105
// List all the agent pools of the given organization.
@@ -186,7 +195,7 @@ type AgentPoolUpdateOptions struct {
186195
OrganizationScoped *bool `jsonapi:"attr,organization-scoped,omitempty"`
187196

188197
// A new list of workspaces that are associated with an agent pool.
189-
AllowedWorkspaces []*Workspace `jsonapi:"relation,allowed-workspaces"`
198+
AllowedWorkspaces []*Workspace `jsonapi:"relation,allowed-workspaces,omitempty"`
190199
}
191200

192201
// Update an agent pool by its ID.

agent_pool_integration_test.go

+72
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,47 @@ func TestAgentPoolsList(t *testing.T) {
8484
require.NoError(t, err)
8585
assert.Empty(t, pools.Items)
8686
})
87+
88+
t.Run("with allowed workspace name filter", func(t *testing.T) {
89+
ws1, ws1TestCleanup := createWorkspace(t, client, orgTest)
90+
defer ws1TestCleanup()
91+
92+
ws2, ws2TestCleanup := createWorkspace(t, client, orgTest)
93+
defer ws2TestCleanup()
94+
95+
organizationScoped := false
96+
ap, apCleanup := createAgentPoolWithOptions(t, client, orgTest, AgentPoolCreateOptions{
97+
Name: String("a-pool"),
98+
OrganizationScoped: &organizationScoped,
99+
AllowedWorkspaces: []*Workspace{ws1},
100+
})
101+
defer apCleanup()
102+
103+
ap2, ap2Cleanup := createAgentPoolWithOptions(t, client, orgTest, AgentPoolCreateOptions{
104+
Name: String("b-pool"),
105+
OrganizationScoped: &organizationScoped,
106+
AllowedWorkspaces: []*Workspace{ws2},
107+
})
108+
defer ap2Cleanup()
109+
110+
pools, err := client.AgentPools.List(ctx, orgTest.Name, &AgentPoolListOptions{
111+
AllowedWorkspacesName: ws1.Name,
112+
})
113+
require.NoError(t, err)
114+
assert.NotEmpty(t, pools.Items)
115+
assert.Contains(t, pools.Items, ap)
116+
assert.Contains(t, pools.Items, agentPool)
117+
assert.Equal(t, 2, pools.TotalCount)
118+
119+
pools, err = client.AgentPools.List(ctx, orgTest.Name, &AgentPoolListOptions{
120+
AllowedWorkspacesName: ws2.Name,
121+
})
122+
require.NoError(t, err)
123+
assert.NotEmpty(t, pools.Items)
124+
assert.Contains(t, pools.Items, agentPool)
125+
assert.Contains(t, pools.Items, ap2)
126+
assert.Equal(t, 2, pools.TotalCount)
127+
})
87128
}
88129

89130
func TestAgentPoolsCreate(t *testing.T) {
@@ -128,6 +169,37 @@ func TestAgentPoolsCreate(t *testing.T) {
128169
assert.Nil(t, pool)
129170
assert.EqualError(t, err, ErrInvalidOrg.Error())
130171
})
172+
173+
t.Run("with allowed-workspaces options", func(t *testing.T) {
174+
workspaceTest, workspaceTestCleanup := createWorkspace(t, client, orgTest)
175+
defer workspaceTestCleanup()
176+
177+
organizationScoped := false
178+
options := AgentPoolCreateOptions{
179+
Name: String("a-pool"),
180+
OrganizationScoped: &organizationScoped,
181+
AllowedWorkspaces: []*Workspace{
182+
workspaceTest,
183+
},
184+
}
185+
186+
pool, err := client.AgentPools.Create(ctx, orgTest.Name, options)
187+
require.NoError(t, err)
188+
189+
assert.Equal(t, 1, len(pool.AllowedWorkspaces))
190+
assert.Equal(t, workspaceTest.ID, pool.AllowedWorkspaces[0].ID)
191+
192+
// Get a refreshed view from the API.
193+
refreshed, err := client.AgentPools.Read(ctx, pool.ID)
194+
require.NoError(t, err)
195+
196+
for _, item := range []*AgentPool{
197+
pool,
198+
refreshed,
199+
} {
200+
assert.NotEmpty(t, item.ID)
201+
}
202+
})
131203
}
132204

133205
func TestAgentPoolsRead(t *testing.T) {

helper_test.go

+26
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,32 @@ func createAgentPool(t *testing.T, client *Client, org *Organization) (*AgentPoo
339339
}
340340
}
341341

342+
func createAgentPoolWithOptions(t *testing.T, client *Client, org *Organization, opts AgentPoolCreateOptions) (*AgentPool, func()) {
343+
var orgCleanup func()
344+
345+
if org == nil {
346+
org, orgCleanup = createOrganization(t, client)
347+
}
348+
349+
ctx := context.Background()
350+
pool, err := client.AgentPools.Create(ctx, org.Name, opts)
351+
if err != nil {
352+
t.Fatal(err)
353+
}
354+
355+
return pool, func() {
356+
if err := client.AgentPools.Delete(ctx, pool.ID); err != nil {
357+
t.Logf("Error destroying agent pool! WARNING: Dangling resources "+
358+
"may exist! The full error is shown below.\n\n"+
359+
"Agent pool ID: %s\nError: %s", pool.ID, err)
360+
}
361+
362+
if orgCleanup != nil {
363+
orgCleanup()
364+
}
365+
}
366+
}
367+
342368
func createAgentToken(t *testing.T, client *Client, ap *AgentPool) (*AgentToken, func()) {
343369
var apCleanup func()
344370

variable_set.go

-2
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,6 @@ func (s *variableSets) RemoveFromWorkspaces(ctx context.Context, variableSetID s
381381

382382
// ApplyToProjects applies the variable set to projects in the supplied list.
383383
// This method will return an error if the variable set has global = true.
384-
// **Note: This feature is still in BETA and subject to change.**
385384
func (s variableSets) ApplyToProjects(ctx context.Context, variableSetID string, options VariableSetApplyToProjectsOptions) error {
386385
if !validStringID(&variableSetID) {
387386
return ErrInvalidVariableSetID
@@ -401,7 +400,6 @@ func (s variableSets) ApplyToProjects(ctx context.Context, variableSetID string,
401400

402401
// RemoveFromProjects removes the variable set from projects in the supplied list.
403402
// This method will return an error if the variable set has global = true.
404-
// **Note: This feature is still in BETA and subject to change.**
405403
func (s variableSets) RemoveFromProjects(ctx context.Context, variableSetID string, options VariableSetRemoveFromProjectsOptions) error {
406404
if !validStringID(&variableSetID) {
407405
return ErrInvalidVariableSetID

0 commit comments

Comments
 (0)