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

[DO NOT MERGE] Update Org and Run Tasks for Private Run Tasks #944

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# UNRELEASED

## Enhancements

* Adds `AllowMemberTokenManagement` permission to `Team` by @juliannatetreault [#922](https://github.com/hashicorp/go-tfe/pull/922)
* Adds `PrivateRunTasks` field to Entitlements by @glennsarti [#944](https://github.com/hashicorp/go-tfe/pull/944)
* Adds `AgentPool` relationship to options when creating and updating Run Tasks by @glennsarti [#944](https://github.com/hashicorp/go-tfe/pull/944)

# v1.61.0

Expand Down
1 change: 1 addition & 0 deletions organization.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ type Entitlements struct {
GlobalRunTasks bool `jsonapi:"attr,global-run-tasks"`
Operations bool `jsonapi:"attr,operations"`
PrivateModuleRegistry bool `jsonapi:"attr,private-module-registry"`
PrivateRunTasks bool `jsonapi:"attr,private-run-tasks"`
RunTasks bool `jsonapi:"attr,run-tasks"`
SSO bool `jsonapi:"attr,sso"`
Sentinel bool `jsonapi:"attr,sentinel"`
Expand Down
9 changes: 9 additions & 0 deletions run_task.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ type RunTask struct {
Enabled bool `jsonapi:"attr,enabled"`
Global *GlobalRunTask `jsonapi:"attr,global-configuration,omitempty"`

AgentPool *AgentPool `jsonapi:"relation,agent-pool"`
Organization *Organization `jsonapi:"relation,organization"`
WorkspaceRunTasks []*WorkspaceRunTask `jsonapi:"relation,workspace-tasks"`
}
Expand Down Expand Up @@ -130,6 +131,10 @@ type RunTaskCreateOptions struct {

// Optional: Whether the task contains global configuration
Global *GlobalRunTaskOptions `jsonapi:"attr,global-configuration,omitempty"`

// Optional: Whether the task will be executed using an Agent Pool
// Requires the PrivateRunTasks entitlement
AgentPool *AgentPool `jsonapi:"relation,agent-pool,omitempty"`
}

// RunTaskUpdateOptions represents the set of options for updating an organization's run task
Expand Down Expand Up @@ -160,6 +165,10 @@ type RunTaskUpdateOptions struct {

// Optional: Whether the task contains global configuration
Global *GlobalRunTaskOptions `jsonapi:"attr,global-configuration,omitempty"`

// Optional: Whether the task will be executed using an Agent Pool
// Requires the PrivateRunTasks entitlement
AgentPool *AgentPool `jsonapi:"relation,agent-pool,omitempty"`
}

// Create is used to create a new run task for an organization
Expand Down
79 changes: 73 additions & 6 deletions run_task_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,32 @@ import (
"github.com/stretchr/testify/require"
)

func hasGlobalRunTasks(client *Client, organizationName string) (bool, error) {
func getOrgEntitlements(client *Client, organizationName string) (*Entitlements, error) {
ctx := context.Background()
if orgEntitlements, err := client.Organizations.ReadEntitlements(ctx, organizationName); err != nil {
orgEntitlements, err := client.Organizations.ReadEntitlements(ctx, organizationName)
if err != nil {
return nil, err
}
if orgEntitlements == nil {
return nil, errors.New("The organization entitlements are empty.")
}
return orgEntitlements, nil
}

func hasGlobalRunTasks(client *Client, organizationName string) (bool, error) {
oe, err := getOrgEntitlements(client, organizationName)
if err != nil {
return false, err
} else if orgEntitlements == nil {
return false, errors.New("The organization entitlements are empty.")
} else {
return orgEntitlements.GlobalRunTasks, nil
}
return oe.GlobalRunTasks, nil
}

func hasPrivateRunTasks(client *Client, organizationName string) (bool, error) {
oe, err := getOrgEntitlements(client, organizationName)
if err != nil {
return false, err
}
return oe.PrivateRunTasks, nil
}

func TestRunTasksCreate(t *testing.T) {
Expand Down Expand Up @@ -54,6 +71,33 @@ func TestRunTasksCreate(t *testing.T) {
}
globalEnforce := Mandatory

t.Run("with an agent pool", func(t *testing.T) {
// We can only test if the org, supports private run tasks. For now this isn't
// a fatal error and we just skip the test.
if v, err := hasPrivateRunTasks(client, orgTest.Name); err != nil {
t.Fatalf("Could not retrieve the entitlements for the test organization.: %s", err)
} else if !v {
t.Skip("The test organization requires the private-run-tasks entitlement but is not entitled.")
return
}

// Unfortunately when we create a Run Task it automatically verifies that the URL by sending a test payload. But
// this means with an agent pool, we need an agent pool to exist, and an agent created with request forwarding enabled.
// This is too much to create for this one test suite. So instead, we really only need to assert that; when the options include an
// agent pool, then we expect HCP Terraform to process the agent pool. So, if we send it a nonsense agent pool ID, then we
// expect an error to be returned saying that the ID was nonsense.
_, err := client.RunTasks.Create(ctx, orgTest.Name, RunTaskCreateOptions{
Name: runTaskName,
URL: runTaskServerURL,
Description: &runTaskDescription,
Category: "task",
AgentPool: &AgentPool{
ID: "apool-this-pool-id-will-never-exist-so-we-expect-http-error-response",
},
})
require.ErrorContains(t, err, "The provided agent pool does not exist")
})

t.Run("add run task to organization", func(t *testing.T) {
r, err := client.RunTasks.Create(ctx, orgTest.Name, RunTaskCreateOptions{
Name: runTaskName,
Expand Down Expand Up @@ -262,6 +306,29 @@ func TestRunTasksUpdate(t *testing.T) {

assert.Equal(t, newDescription, r.Description)
})

t.Run("with an agent pool", func(t *testing.T) {
// We can only test if the org, supports private run tasks. For now this isn't
// a fatal error and we just skip the test.
if v, err := hasPrivateRunTasks(client, orgTest.Name); err != nil {
t.Fatalf("Could not retrieve the entitlements for the test organization.: %s", err)
} else if !v {
t.Skip("The test organization requires the private-run-tasks entitlement but is not entitled.")
return
}

// Unfortunately when we update a Run Task it automatically verifies that the URL by sending a test payload. But
// this means with an agent pool, we need an agent pool to exist, and an agent created with request forwarding enabled.
// This is too much to create for this one test suite. So instead, we really only need to assert that; when the options include an
// agent pool, then we expect HCP Terraform to process the agent pool. So, if we send it a nonsense agent pool ID, then we
// expect an error to be returned saying that the ID was nonsense.
_, err := client.RunTasks.Update(ctx, runTaskTest.ID, RunTaskUpdateOptions{
AgentPool: &AgentPool{
ID: "apool-this-pool-id-will-never-exist-so-we-expect-http-error-response",
},
})
require.ErrorContains(t, err, "The provided agent pool does not exist")
})
}

func TestRunTasksDelete(t *testing.T) {
Expand Down
1 change: 1 addition & 0 deletions task_result.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ type TaskResult struct {
TaskURL string `jsonapi:"attr,task-url"`
WorkspaceTaskID string `jsonapi:"attr,workspace-task-id"`
WorkspaceTaskEnforcementLevel TaskEnforcementLevel `jsonapi:"attr,workspace-task-enforcement-level"`
AgentPoolID *string `jsonapi:"attr,agent-pool-id,omitempty"`

// The task stage this result belongs to
TaskStage *TaskStage `jsonapi:"relation,task_stage"`
Expand Down
Loading