diff --git a/CHANGELOG.md b/CHANGELOG.md index bc98e3de0..f11364b37 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,9 @@ ENHANCEMENTS: * `d/tfe_project`: Add `workspace_names` attribute, by @1natedawg [#1429](https://github.com/hashicorp/terraform-provider-tfe/pull/1429) +FEATURES: +* `r/tfe_team`: Add attribute `allow_member_token_management` to `tfe_team` by @juliannatetreault [#1398](https://github.com/hashicorp/terraform-provider-tfe/pull/1398) + BUG FIXES: * `r/tfe_workspace` html_url is now planned to be recomputed when `name` changes. Previously, changed values would show up on the next plan, by @brandonc [1422](https://github.com/hashicorp/terraform-provider-tfe/issues/1422) diff --git a/go.mod b/go.mod index 8bdf47fc0..2610f168a 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-retryablehttp v0.7.7 // indirect github.com/hashicorp/go-slug v0.15.2 - github.com/hashicorp/go-tfe v1.58.0 + github.com/hashicorp/go-tfe v1.62.0 github.com/hashicorp/go-version v1.7.0 github.com/hashicorp/hcl v1.0.0 github.com/hashicorp/hcl/v2 v2.19.1 // indirect @@ -28,9 +28,9 @@ require ( golang.org/x/crypto v0.21.0 // indirect golang.org/x/net v0.23.0 // indirect golang.org/x/oauth2 v0.17.0 // indirect - golang.org/x/sys v0.20.0 // indirect + golang.org/x/sys v0.23.0 // indirect golang.org/x/text v0.14.0 // indirect - golang.org/x/time v0.5.0 // indirect + golang.org/x/time v0.6.0 // indirect google.golang.org/protobuf v1.33.0 // indirect ) @@ -76,7 +76,7 @@ require ( github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect golang.org/x/mod v0.15.0 // indirect - golang.org/x/sync v0.7.0 // indirect + golang.org/x/sync v0.8.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 415632fda..330b67b1b 100644 --- a/go.sum +++ b/go.sum @@ -68,6 +68,8 @@ github.com/hashicorp/go-slug v0.15.2 h1:/ioIpE4bWVN/d7pG2qMrax0a7xe9vOA66S+fz7fZ github.com/hashicorp/go-slug v0.15.2/go.mod h1:THWVTAXwJEinbsp4/bBRcmbaO5EYNLTqxbG4tZ3gCYQ= github.com/hashicorp/go-tfe v1.58.0 h1:aJXrStDBG+YJLkgDYswfNiKTRHQxKqT/9C1VuvujRkE= github.com/hashicorp/go-tfe v1.58.0/go.mod h1:XnTtBj3tVQ4uFkcFsv8Grn+O1CVcIcceL1uc2AgUcaU= +github.com/hashicorp/go-tfe v1.62.0 h1:YCosV7nUQLAnZ+oYN2Mco3pP2ZjqW+3P5utZgKYptGc= +github.com/hashicorp/go-tfe v1.62.0/go.mod h1:QyiMW7cc0jCYeiY0qYDOy6V2T1YmlF+wOKs96rxITBA= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= @@ -187,6 +189,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -201,6 +205,8 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= +golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -212,6 +218,8 @@ golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= +golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= diff --git a/internal/provider/resource_tfe_team.go b/internal/provider/resource_tfe_team.go index 937ceffc1..dac0028a5 100644 --- a/internal/provider/resource_tfe_team.go +++ b/internal/provider/resource_tfe_team.go @@ -141,6 +141,11 @@ func resourceTFETeam() *schema.Resource { Type: schema.TypeString, Optional: true, }, + "allow_member_token_management": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, }, } } @@ -190,6 +195,8 @@ func resourceTFETeamCreate(d *schema.ResourceData, meta interface{}) error { options.SSOTeamID = tfe.String(v.(string)) } + options.AllowMemberTokenManagement = tfe.Bool(d.Get("allow_member_token_management").(bool)) + log.Printf("[DEBUG] Create team %s for organization: %s", name, organization) team, err := config.Client.Teams.Create(ctx, organization, options) if err != nil { @@ -250,6 +257,7 @@ func resourceTFETeamRead(d *schema.ResourceData, meta interface{}) error { } d.Set("visibility", team.Visibility) d.Set("sso_team_id", team.SSOTeamID) + d.Set("allow_member_token_management", team.AllowMemberTokenManagement) return nil } @@ -297,6 +305,8 @@ func resourceTFETeamUpdate(d *schema.ResourceData, meta interface{}) error { options.SSOTeamID = tfe.String("") } + options.AllowMemberTokenManagement = tfe.Bool(d.Get("allow_member_token_management").(bool)) + log.Printf("[DEBUG] Update team: %s", d.Id()) _, err := config.Client.Teams.Update(ctx, d.Id(), options) if err != nil { diff --git a/internal/provider/resource_tfe_team_test.go b/internal/provider/resource_tfe_team_test.go index a64042e47..0e66d264a 100644 --- a/internal/provider/resource_tfe_team_test.go +++ b/internal/provider/resource_tfe_team_test.go @@ -57,6 +57,8 @@ func TestAccTFETeam_full(t *testing.T) { "tfe_team.foobar", "name", "team-test"), resource.TestCheckResourceAttr( "tfe_team.foobar", "visibility", "organization"), + resource.TestCheckResourceAttr( + "tfe_team.foobar", "allow_member_token_management", "true"), resource.TestCheckResourceAttr( "tfe_team.foobar", "organization_access.0.manage_policies", "true"), resource.TestCheckResourceAttr( @@ -112,6 +114,8 @@ func TestAccTFETeam_full_update(t *testing.T) { "tfe_team.foobar", "name", "team-test"), resource.TestCheckResourceAttr( "tfe_team.foobar", "visibility", "organization"), + resource.TestCheckResourceAttr( + "tfe_team.foobar", "allow_member_token_management", "true"), resource.TestCheckResourceAttr( "tfe_team.foobar", "organization_access.0.manage_policies", "true"), resource.TestCheckResourceAttr( @@ -154,6 +158,8 @@ func TestAccTFETeam_full_update(t *testing.T) { "tfe_team.foobar", "name", "team-test-1"), resource.TestCheckResourceAttr( "tfe_team.foobar", "visibility", "secret"), + resource.TestCheckResourceAttr( + "tfe_team.foobar", "allow_member_token_management", "false"), resource.TestCheckResourceAttr( "tfe_team.foobar", "organization_access.0.manage_policies", "false"), resource.TestCheckResourceAttr( @@ -195,6 +201,8 @@ func TestAccTFETeam_full_update(t *testing.T) { "tfe_team.foobar", "name", "team-test-1"), resource.TestCheckResourceAttr( "tfe_team.foobar", "visibility", "secret"), + resource.TestCheckResourceAttr( + "tfe_team.foobar", "allow_member_token_management", "true"), resource.TestCheckResourceAttr( "tfe_team.foobar", "organization_access.0.manage_policies", "false"), resource.TestCheckResourceAttr( @@ -461,6 +469,10 @@ func testAccCheckTFETeamAttributes_full( return fmt.Errorf("Bad visibility: %s", team.Visibility) } + if !team.AllowMemberTokenManagement { + return fmt.Errorf("team.AllowMemberTokenManagement should be true") + } + if !team.OrganizationAccess.ManagePolicies { return fmt.Errorf("OrganizationAccess.ManagePolicies should be true") } @@ -511,6 +523,10 @@ func testAccCheckTFETeamAttributes_full_update( return fmt.Errorf("Bad visibility: %s", team.Visibility) } + if team.AllowMemberTokenManagement { + return fmt.Errorf("team.AllowMemberTokenManagement should be false") + } + if team.OrganizationAccess.ManagePolicies { return fmt.Errorf("OrganizationAccess.ManagePolicies should be false") } @@ -596,6 +612,7 @@ resource "tfe_team" "foobar" { organization = tfe_organization.foobar.id visibility = "organization" + allow_member_token_management = true organization_access { manage_policies = true @@ -630,6 +647,7 @@ resource "tfe_team" "foobar" { organization = tfe_organization.foobar.id visibility = "secret" + allow_member_token_management = false organization_access { manage_policies = false diff --git a/website/docs/r/team.html.markdown b/website/docs/r/team.html.markdown index fb67f1ad1..a6d792726 100644 --- a/website/docs/r/team.html.markdown +++ b/website/docs/r/team.html.markdown @@ -41,6 +41,7 @@ The following arguments are supported: * `visibility` - (Optional) The visibility of the team ("secret" or "organization"). Defaults to "secret". * `organization_access` - (Optional) Settings for the team's [organization access](https://developer.hashicorp.com/terraform/cloud-docs/users-teams-organizations/permissions#organization-permissions). * `sso_team_id` - (Optional) Unique Identifier to control [team membership](https://developer.hashicorp.com/terraform/cloud-docs/users-teams-organizations/single-sign-on#team-names-and-sso-team-ids) via SAML. Defaults to `null` +* `allow_member_token_management` - (Optional) Used by Owners and users with "Manage Teams" permissions to control whether team members can manage team tokens. Defaults to `true`. The `organization_access` block supports: