Skip to content

Commit

Permalink
Add run_tasks permission to Team Access
Browse files Browse the repository at this point in the history
Run Tasks has added a new `run_tasks` custom permission to Team
Workspace access.  This commit adds this new permission to the
Team Access object (both resource and data) and adds acceptance
tests for both objects.
  • Loading branch information
glennsarti committed May 5, 2022
1 parent 1f9fc01 commit 50a77fc
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 1 deletion.
5 changes: 5 additions & 0 deletions tfe/data_source_team_access.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ func dataSourceTFETeamAccess() *schema.Resource {
Type: schema.TypeBool,
Computed: true,
},

"run_tasks": {
Type: schema.TypeBool,
Computed: true,
},
},
},
},
Expand Down
2 changes: 2 additions & 0 deletions tfe/data_source_team_access_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ func TestAccTFETeamAccessDataSource_basic(t *testing.T) {
"data.tfe_team_access.foobar", "permissions.0.sentinel_mocks", "read"),
resource.TestCheckResourceAttr(
"data.tfe_team_access.foobar", "permissions.0.workspace_locking", "true"),
resource.TestCheckResourceAttr(
"data.tfe_team_access.foobar", "permissions.0.run_tasks", "false"),
resource.TestCheckResourceAttrSet("data.tfe_team_access.foobar", "id"),
resource.TestCheckResourceAttrSet("data.tfe_team_access.foobar", "team_id"),
resource.TestCheckResourceAttrSet("data.tfe_team_access.foobar", "workspace_id"),
Expand Down
28 changes: 27 additions & 1 deletion tfe/resource_tfe_team_access.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@ func resourceTFETeamAccess() *schema.Resource {
Type: schema.TypeBool,
Required: true,
},

"run_tasks": {
Type: schema.TypeBool,
Required: true,
},
},
},
},
Expand Down Expand Up @@ -193,6 +198,12 @@ func resourceTFETeamAccessCreate(d *schema.ResourceData, meta interface{}) error
}
}

if d.HasChange("permissions.0.run_tasks") {
if v, ok := d.GetOkExists("permissions.0.run_tasks"); ok {
options.RunTasks = tfe.Bool(v.(bool))
}
}

log.Printf("[DEBUG] Give team %s %s access to workspace: %s", tm.Name, access, ws.Name)
tmAccess, err := tfeClient.TeamAccess.Add(ctx, options)
if err != nil {
Expand Down Expand Up @@ -227,6 +238,7 @@ func resourceTFETeamAccessRead(d *schema.ResourceData, meta interface{}) error {
"state_versions": tmAccess.StateVersions,
"sentinel_mocks": tmAccess.SentinelMocks,
"workspace_locking": tmAccess.WorkspaceLocking,
"run_tasks": tmAccess.RunTasks,
}}
if err := d.Set("permissions", permissions); err != nil {
return fmt.Errorf("error setting permissions for team access %s: %s", d.Id(), err)
Expand Down Expand Up @@ -281,6 +293,12 @@ func resourceTFETeamAccessUpdate(d *schema.ResourceData, meta interface{}) error
}
}

if d.HasChange("permissions.0.run_tasks") {
if v, ok := d.GetOkExists("permissions.0.run_tasks"); ok {
options.RunTasks = tfe.Bool(v.(bool))
}
}

log.Printf("[DEBUG] Update team access: %s", d.Id())
tmAccess, err := tfeClient.TeamAccess.Update(ctx, d.Id(), options)
if err != nil {
Expand All @@ -295,6 +313,7 @@ func resourceTFETeamAccessUpdate(d *schema.ResourceData, meta interface{}) error
"state_versions": tmAccess.StateVersions,
"sentinel_mocks": tmAccess.SentinelMocks,
"workspace_locking": tmAccess.WorkspaceLocking,
"run_tasks": tmAccess.RunTasks,
}}
if err := d.Set("permissions", permissions); err != nil {
return fmt.Errorf("error setting permissions for team access %s: %s", d.Id(), err)
Expand Down Expand Up @@ -397,7 +416,14 @@ func setCustomAccess(d *schema.ResourceDiff) error {
// Interpolated values not known at plan time are not allowed because we cannot re-check
// for a change in permissions later - when the plan is expanded for new values learned during
// an apply. This creates an inconsistent final plan and causes an error.
for _, permission := range []string{"permissions.0.runs", "permissions.0.variables", "permissions.0.state_versions", "permissions.0.sentinel_mocks", "permissions.0.workspace_locking"} {
for _, permission := range []string{
"permissions.0.runs",
"permissions.0.variables",
"permissions.0.state_versions",
"permissions.0.sentinel_mocks",
"permissions.0.workspace_locking",
"permissions.0.run_tasks",
} {
if !d.NewValueKnown(permission) {
return fmt.Errorf("'%q' cannot be derived from a value that is unknown during planning", permission)
}
Expand Down
78 changes: 78 additions & 0 deletions tfe/resource_tfe_team_access_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,44 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
)

func TestAccTFETeamAccess_admin(t *testing.T) {
tmAccess := &tfe.TeamAccess{}
rInt := rand.New(rand.NewSource(time.Now().UnixNano())).Int()

expectedPermissions := map[string]interface{}{
"runs": tfe.RunsPermissionApply,
"variables": tfe.VariablesPermissionWrite,
"state_versions": tfe.StateVersionsPermissionWrite,
"sentinel_mocks": tfe.SentinelMocksPermissionRead,
"workspace_locking": true,
"run_tasks": true,
}

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckTFETeamAccessDestroy,
Steps: []resource.TestStep{
{
Config: testAccTFETeamAccess_admin(rInt),
Check: resource.ComposeTestCheckFunc(
testAccCheckTFETeamAccessExists(
"tfe_team_access.foobar", tmAccess),
testAccCheckTFETeamAccessAttributesAccessIs(tmAccess, tfe.AccessAdmin),
testAccCheckTFETeamAccessAttributesPermissionsAre(tmAccess, expectedPermissions),
resource.TestCheckResourceAttr("tfe_team_access.foobar", "access", "admin"),
resource.TestCheckResourceAttr("tfe_team_access.foobar", "permissions.0.runs", "apply"),
resource.TestCheckResourceAttr("tfe_team_access.foobar", "permissions.0.variables", "write"),
resource.TestCheckResourceAttr("tfe_team_access.foobar", "permissions.0.state_versions", "write"),
resource.TestCheckResourceAttr("tfe_team_access.foobar", "permissions.0.sentinel_mocks", "read"),
resource.TestCheckResourceAttr("tfe_team_access.foobar", "permissions.0.workspace_locking", "true"),
resource.TestCheckResourceAttr("tfe_team_access.foobar", "permissions.0.run_tasks", "true"),
),
},
},
})
}

func TestAccTFETeamAccess_write(t *testing.T) {
tmAccess := &tfe.TeamAccess{}
rInt := rand.New(rand.NewSource(time.Now().UnixNano())).Int()
Expand All @@ -21,6 +59,7 @@ func TestAccTFETeamAccess_write(t *testing.T) {
"state_versions": tfe.StateVersionsPermissionWrite,
"sentinel_mocks": tfe.SentinelMocksPermissionRead,
"workspace_locking": true,
"run_tasks": false,
}

resource.Test(t, resource.TestCase{
Expand All @@ -41,6 +80,7 @@ func TestAccTFETeamAccess_write(t *testing.T) {
resource.TestCheckResourceAttr("tfe_team_access.foobar", "permissions.0.state_versions", "write"),
resource.TestCheckResourceAttr("tfe_team_access.foobar", "permissions.0.sentinel_mocks", "read"),
resource.TestCheckResourceAttr("tfe_team_access.foobar", "permissions.0.workspace_locking", "true"),
resource.TestCheckResourceAttr("tfe_team_access.foobar", "permissions.0.run_tasks", "false"),
),
},
},
Expand Down Expand Up @@ -70,6 +110,7 @@ func TestAccTFETeamAccess_custom(t *testing.T) {
"state_versions": tfe.StateVersionsPermissionReadOutputs,
"sentinel_mocks": tfe.SentinelMocksPermissionNone,
"workspace_locking": false,
"run_tasks": false,
},
),
resource.TestCheckResourceAttr("tfe_team_access.foobar", "access", "custom"),
Expand All @@ -78,6 +119,7 @@ func TestAccTFETeamAccess_custom(t *testing.T) {
resource.TestCheckResourceAttr("tfe_team_access.foobar", "permissions.0.state_versions", "read-outputs"),
resource.TestCheckResourceAttr("tfe_team_access.foobar", "permissions.0.sentinel_mocks", "none"),
resource.TestCheckResourceAttr("tfe_team_access.foobar", "permissions.0.workspace_locking", "false"),
resource.TestCheckResourceAttr("tfe_team_access.foobar", "permissions.0.run_tasks", "false"),
),
},
},
Expand Down Expand Up @@ -107,6 +149,7 @@ func TestAccTFETeamAccess_updateToCustom(t *testing.T) {
"state_versions": tfe.StateVersionsPermissionWrite,
"sentinel_mocks": tfe.SentinelMocksPermissionRead,
"workspace_locking": true,
"run_tasks": false,
},
),
resource.TestCheckResourceAttr("tfe_team_access.foobar", "access", "write"),
Expand All @@ -115,6 +158,7 @@ func TestAccTFETeamAccess_updateToCustom(t *testing.T) {
resource.TestCheckResourceAttr("tfe_team_access.foobar", "permissions.0.state_versions", "write"),
resource.TestCheckResourceAttr("tfe_team_access.foobar", "permissions.0.sentinel_mocks", "read"),
resource.TestCheckResourceAttr("tfe_team_access.foobar", "permissions.0.workspace_locking", "true"),
resource.TestCheckResourceAttr("tfe_team_access.foobar", "permissions.0.run_tasks", "false"),
),
},
{
Expand All @@ -131,6 +175,7 @@ func TestAccTFETeamAccess_updateToCustom(t *testing.T) {
"state_versions": tfe.StateVersionsPermissionReadOutputs,
"sentinel_mocks": tfe.SentinelMocksPermissionNone,
"workspace_locking": false,
"run_tasks": false,
},
),
resource.TestCheckResourceAttr("tfe_team_access.foobar", "access", "custom"),
Expand All @@ -139,6 +184,7 @@ func TestAccTFETeamAccess_updateToCustom(t *testing.T) {
resource.TestCheckResourceAttr("tfe_team_access.foobar", "permissions.0.state_versions", "read-outputs"),
resource.TestCheckResourceAttr("tfe_team_access.foobar", "permissions.0.sentinel_mocks", "none"),
resource.TestCheckResourceAttr("tfe_team_access.foobar", "permissions.0.workspace_locking", "false"),
resource.TestCheckResourceAttr("tfe_team_access.foobar", "permissions.0.run_tasks", "false"),
),
},
},
Expand Down Expand Up @@ -168,6 +214,7 @@ func TestAccTFETeamAccess_updateFromCustom(t *testing.T) {
"state_versions": tfe.StateVersionsPermissionReadOutputs,
"sentinel_mocks": tfe.SentinelMocksPermissionNone,
"workspace_locking": false,
"run_tasks": false,
},
),
resource.TestCheckResourceAttr("tfe_team_access.foobar", "access", "custom"),
Expand All @@ -176,6 +223,7 @@ func TestAccTFETeamAccess_updateFromCustom(t *testing.T) {
resource.TestCheckResourceAttr("tfe_team_access.foobar", "permissions.0.state_versions", "read-outputs"),
resource.TestCheckResourceAttr("tfe_team_access.foobar", "permissions.0.sentinel_mocks", "none"),
resource.TestCheckResourceAttr("tfe_team_access.foobar", "permissions.0.workspace_locking", "false"),
resource.TestCheckResourceAttr("tfe_team_access.foobar", "permissions.0.run_tasks", "false"),
),
},
{
Expand All @@ -192,6 +240,7 @@ func TestAccTFETeamAccess_updateFromCustom(t *testing.T) {
"state_versions": tfe.StateVersionsPermissionRead,
"sentinel_mocks": tfe.SentinelMocksPermissionNone,
"workspace_locking": false,
"run_tasks": false,
},
),
resource.TestCheckResourceAttr("tfe_team_access.foobar", "access", "plan"),
Expand All @@ -200,6 +249,7 @@ func TestAccTFETeamAccess_updateFromCustom(t *testing.T) {
resource.TestCheckResourceAttr("tfe_team_access.foobar", "permissions.0.state_versions", "read"),
resource.TestCheckResourceAttr("tfe_team_access.foobar", "permissions.0.sentinel_mocks", "none"),
resource.TestCheckResourceAttr("tfe_team_access.foobar", "permissions.0.workspace_locking", "false"),
resource.TestCheckResourceAttr("tfe_team_access.foobar", "permissions.0.run_tasks", "false"),
),
},
},
Expand Down Expand Up @@ -283,6 +333,9 @@ func testAccCheckTFETeamAccessAttributesPermissionsAre(tmAccess *tfe.TeamAccess,
if tmAccess.WorkspaceLocking != expectedPermissions["workspace_locking"].(bool) {
return fmt.Errorf("Bad workspace-locking permission: Expected %s, Received %t", expectedPermissions["workspace_locking"], tmAccess.WorkspaceLocking)
}
if tmAccess.RunTasks != expectedPermissions["run_tasks"].(bool) {
return fmt.Errorf("Bad run_tasks permission: Expected %s, Received %t", expectedPermissions["run_tasks"], tmAccess.RunTasks)
}
return nil
}
}
Expand All @@ -308,6 +361,30 @@ func testAccCheckTFETeamAccessDestroy(s *terraform.State) error {
return nil
}

func testAccTFETeamAccess_admin(rInt int) string {
return fmt.Sprintf(`
resource "tfe_organization" "foobar" {
name = "tst-terraform-%d"
email = "admin@company.com"
}
resource "tfe_team" "foobar" {
name = "team-test"
organization = tfe_organization.foobar.id
}
resource "tfe_workspace" "foobar" {
name = "workspace-test"
organization = tfe_organization.foobar.id
}
resource "tfe_team_access" "foobar" {
access = "admin"
team_id = tfe_team.foobar.id
workspace_id = tfe_workspace.foobar.id
}`, rInt)
}

func testAccTFETeamAccess_write(rInt int) string {
return fmt.Sprintf(`
resource "tfe_organization" "foobar" {
Expand Down Expand Up @@ -380,6 +457,7 @@ resource "tfe_team_access" "foobar" {
state_versions = "read-outputs"
sentinel_mocks = "none"
workspace_locking = false
run_tasks = false
}
team_id = tfe_team.foobar.id
workspace_id = tfe_workspace.foobar.id
Expand Down

0 comments on commit 50a77fc

Please sign in to comment.