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

Add UpdateAllowedWorkspaces method to Agent Pool #701

Merged
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
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# UNRELEASED

## Bug Fixes
* AgentPool `Update` was previously not able to remove all allowed workspaces from an agent pool. `AllowedWorkspaces` has been removed from `AgentPoolUpdateOptions` and are now handled by a separate `UpdateAllowedWorkspaces` method using `AgentPoolAllowedWorkspacesUpdateOptions`.

# v1.26.0

## Enhancements
Expand All @@ -23,6 +28,7 @@ to the original message using the error `ErrWorkspaceLockedCannotDelete` instead
* Adds `ExpiredAt` field to `OrganizationToken`, `TeamToken`, and `UserToken`. This enhancement will be available in TFE release, v202305-1. @JuliannaTetreault [#672](https://github.com/hashicorp/go-tfe/pull/672)
* Adds `ContextWithResponseHeaderHook` context for use with the ClientRequest Do method that allows callers to define a callback which receives raw http Response headers. @apparentlymart [#689](https://github.com/hashicorp/go-tfe/pull/689)


# v1.23.0

## Features
Expand Down
36 changes: 34 additions & 2 deletions agent_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ type AgentPools interface {
// Update an agent pool by its ID.
Update(ctx context.Context, agentPool string, options AgentPoolUpdateOptions) (*AgentPool, error)

// UpdateAllowedWorkspaces updates the list of allowed workspaces associated with an agent pool.
UpdateAllowedWorkspaces(ctx context.Context, agentPool string, options AgentPoolAllowedWorkspacesUpdateOptions) (*AgentPool, error)

// Delete an agent pool by its ID.
Delete(ctx context.Context, agentPoolID string) error
}
Expand Down Expand Up @@ -189,13 +192,22 @@ type AgentPoolUpdateOptions struct {
Type string `jsonapi:"primary,agent-pools"`

// A new name to identify the agent pool.
Name *string `jsonapi:"attr,name"`
Name *string `jsonapi:"attr,name,omitempty"`

// True if the agent pool is organization scoped, false otherwise.
OrganizationScoped *bool `jsonapi:"attr,organization-scoped,omitempty"`
}

// AgentPoolUpdateAllowedWorkspacesOptions represents the options for updating the allowed workspace on an agent pool
type AgentPoolAllowedWorkspacesUpdateOptions struct {
// Type is a public field utilized by JSON:API to
// set the resource type via the field tag.
// It is not a user-defined value and does not need to be set.
// https://jsonapi.org/format/#crud-creating
Type string `jsonapi:"primary,agent-pools"`

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

// Update an agent pool by its ID.
Expand Down Expand Up @@ -223,6 +235,26 @@ func (s *agentPools) Update(ctx context.Context, agentPoolID string, options Age
return k, nil
}

func (s *agentPools) UpdateAllowedWorkspaces(ctx context.Context, agentPoolID string, options AgentPoolAllowedWorkspacesUpdateOptions) (*AgentPool, error) {
if !validStringID(&agentPoolID) {
return nil, ErrInvalidAgentPoolID
}

u := fmt.Sprintf("agent-pools/%s", url.QueryEscape(agentPoolID))
req, err := s.client.NewRequest("PATCH", u, &options)
if err != nil {
return nil, err
}

k := &AgentPool{}
err = req.Do(ctx, k)
if err != nil {
return nil, err
}

return k, nil
}

// Delete an agent pool by its ID.
func (s *agentPools) Delete(ctx context.Context, agentPoolID string) error {
if !validStringID(&agentPoolID) {
Expand Down
73 changes: 61 additions & 12 deletions agent_pool_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,9 +270,20 @@ func TestAgentPoolsUpdate(t *testing.T) {
assert.NotEqual(t, kBefore.Name, kAfter.Name)
})

t.Run("when updating the name", func(t *testing.T) {
kBefore, kTestCleanup := createAgentPool(t, client, orgTest)
defer kTestCleanup()
t.Run("when updating only the name", func(t *testing.T) {
workspaceTest, workspaceTestCleanup := createWorkspace(t, client, orgTest)
defer workspaceTestCleanup()

organizationScoped := false
options := AgentPoolCreateOptions{
Name: String("a-pool"),
OrganizationScoped: &organizationScoped,
AllowedWorkspaces: []*Workspace{
workspaceTest,
},
}
kBefore, err := client.AgentPools.Create(ctx, orgTest.Name, options)
require.NoError(t, err)

kAfter, err := client.AgentPools.Update(ctx, kBefore.ID, AgentPoolUpdateOptions{
Name: String("updated-key-name"),
Expand All @@ -281,6 +292,8 @@ func TestAgentPoolsUpdate(t *testing.T) {

assert.Equal(t, kBefore.ID, kAfter.ID)
assert.Equal(t, "updated-key-name", kAfter.Name)
assert.Equal(t, 1, len(kAfter.AllowedWorkspaces))
assert.Equal(t, workspaceTest.ID, kAfter.AllowedWorkspaces[0].ID)
})

t.Run("without a valid agent pool ID", func(t *testing.T) {
Expand All @@ -289,39 +302,75 @@ func TestAgentPoolsUpdate(t *testing.T) {
assert.EqualError(t, err, ErrInvalidAgentPoolID.Error())
})

t.Run("when updating organization scope", func(t *testing.T) {
kBefore, kTestCleanup := createAgentPool(t, client, orgTest)
defer kTestCleanup()

organizationScoped := false
kAfter, err := client.AgentPools.Update(ctx, kBefore.ID, AgentPoolUpdateOptions{
Name: String(kBefore.Name),
OrganizationScoped: &organizationScoped,
})
require.NoError(t, err)

assert.NotEqual(t, kBefore.OrganizationScoped, kAfter.OrganizationScoped)
assert.Equal(t, organizationScoped, kAfter.OrganizationScoped)
})
}

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

orgTest, orgTestCleanup := createOrganization(t, client)
defer orgTestCleanup()

upgradeOrganizationSubscription(t, client, orgTest)

t.Run("when updating allowed-workspaces", func(t *testing.T) {
kBefore, kTestCleanup := createAgentPool(t, client, orgTest)
defer kTestCleanup()

workspaceTest, workspaceTestCleanup := createWorkspace(t, client, orgTest)
defer workspaceTestCleanup()

kAfter, err := client.AgentPools.Update(ctx, kBefore.ID, AgentPoolUpdateOptions{
Name: String(kBefore.Name),
kAfter, err := client.AgentPools.UpdateAllowedWorkspaces(ctx, kBefore.ID, AgentPoolAllowedWorkspacesUpdateOptions{
AllowedWorkspaces: []*Workspace{
workspaceTest,
},
})
require.NoError(t, err)

assert.Equal(t, kBefore.Name, kAfter.Name)
assert.NotEqual(t, kBefore.AllowedWorkspaces, kAfter.AllowedWorkspaces)
assert.Equal(t, 1, len(kAfter.AllowedWorkspaces))
assert.Equal(t, workspaceTest.ID, kAfter.AllowedWorkspaces[0].ID)
})

t.Run("when updating organization scope", func(t *testing.T) {
kBefore, kTestCleanup := createAgentPool(t, client, orgTest)
defer kTestCleanup()
t.Run("when removing all the allowed-workspaces", func(t *testing.T) {
workspaceTest, workspaceTestCleanup := createWorkspace(t, client, orgTest)
defer workspaceTestCleanup()

organizationScoped := false
kAfter, err := client.AgentPools.Update(ctx, kBefore.ID, AgentPoolUpdateOptions{
Name: String(kBefore.Name),
options := AgentPoolCreateOptions{
Name: String("a-pool"),
OrganizationScoped: &organizationScoped,
AllowedWorkspaces: []*Workspace{
workspaceTest,
},
}

kBefore, kTestCleanup := createAgentPoolWithOptions(t, client, orgTest, options)
defer kTestCleanup()

kAfter, err := client.AgentPools.UpdateAllowedWorkspaces(ctx, kBefore.ID, AgentPoolAllowedWorkspacesUpdateOptions{
AllowedWorkspaces: []*Workspace{},
})
require.NoError(t, err)

assert.NotEqual(t, kBefore.OrganizationScoped, kAfter.OrganizationScoped)
assert.Equal(t, organizationScoped, kAfter.OrganizationScoped)
assert.Equal(t, kBefore.ID, kAfter.ID)
assert.Equal(t, "a-pool", kAfter.Name)
assert.Empty(t, kAfter.AllowedWorkspaces)
})
}

Expand Down
15 changes: 15 additions & 0 deletions mocks/agent_pool_mocks.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

95 changes: 95 additions & 0 deletions mocks/registry_no_code_module_mocks.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.