Skip to content

Commit 59fdf62

Browse files
authored
Merge branch 'main' into MaxTTLPhase2
2 parents 3c6fe7c + aa7747d commit 59fdf62

28 files changed

Lines changed: 1237 additions & 294 deletions

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
11
## Unreleased
2+
FEATURES:
3+
* Adds a warning message to `r/tfe_team_token`, `r/tfe_organization_token` and `r/tfe_audit_trail_token` resources to indicate that if no `expired_at` attribute is set, the token will expire in 2 years. By @sana-faraz [#1976](https://github.com/hashicorp/terraform-provider-tfe/pull/1976)
4+
5+
BREAKING CHANGES:
6+
* `r/tfe_variable`: Fixed a bug where value_wo continuously resulted in new changes on every terraform apply. By @uk1288 [#1983](https://github.com/hashicorp/terraform-provider-tfe/pull/1983)
7+
* `r/tfe_variable`: Added the `value_wo_version` write-only attribute to allow triggering value_wo updates, by @uk1288 ([#1983](https://github.com/hashicorp/terraform-provider-tfe/pull/1983))
8+
* `r/tfe_test_variable`: Added the `value_wo_version` write-only attribute to allow triggering `value_wo` updates, by @uk1288 ([#1985](https://github.com/hashicorp/terraform-provider-tfe/pull/1985))
9+
* `r/tfe_team_notification_configuration`: Added the `token_wo_version` write-only attribute to allow triggering `token_wo` updates, by @uk1288 ([#1995](https://github.com/hashicorp/terraform-provider-tfe/pull/1995))
10+
* `r/tfe_notification_configuration`: Added the `token_wo_version` write-only attribute to allow triggering token_wo updates, by @uk1288 [#2001](https://github.com/hashicorp/terraform-provider-tfe/pull/2001)
211

312
FEATURES:
413
* Adds `tfe_query_run` action, allowing users to invoke remote Terraform queries on HCP Terraform and Terraform Enterprise, by @sebasslash [#1982](https://github.com/hashicorp/terraform-provider-tfe/pull/1982)
14+
* Adds `d/tfe_current_user` data source for retrieving information about the user associated with the configured API token, by @ShaunakRembhotkar
515

616
## v0.74.1
717

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
// Copyright IBM Corp. 2018, 2025
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package provider
5+
6+
import (
7+
"context"
8+
"fmt"
9+
10+
"github.com/hashicorp/terraform-plugin-framework/datasource"
11+
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
12+
"github.com/hashicorp/terraform-plugin-framework/types"
13+
"github.com/hashicorp/terraform-plugin-log/tflog"
14+
)
15+
16+
var (
17+
_ datasource.DataSource = &dataSourceCurrentUser{}
18+
_ datasource.DataSourceWithConfigure = &dataSourceCurrentUser{}
19+
)
20+
21+
func NewCurrentUserDataSource() datasource.DataSource {
22+
return &dataSourceCurrentUser{}
23+
}
24+
25+
type dataSourceCurrentUser struct {
26+
config ConfiguredClient
27+
}
28+
29+
type modelCurrentUser struct {
30+
ID types.String `tfsdk:"id"`
31+
Username types.String `tfsdk:"username"`
32+
Email types.String `tfsdk:"email"`
33+
IsServiceAccount types.Bool `tfsdk:"is_service_account"`
34+
}
35+
36+
func (d *dataSourceCurrentUser) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
37+
resp.TypeName = req.ProviderTypeName + "_current_user"
38+
}
39+
40+
func (d *dataSourceCurrentUser) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
41+
resp.Schema = schema.Schema{
42+
MarkdownDescription: "Get the current user associated with the API token.",
43+
44+
Attributes: map[string]schema.Attribute{
45+
"id": schema.StringAttribute{
46+
Computed: true,
47+
MarkdownDescription: "Service-generated identifier for the user.",
48+
},
49+
"username": schema.StringAttribute{
50+
Computed: true,
51+
MarkdownDescription: "The username of the current user.",
52+
},
53+
"email": schema.StringAttribute{
54+
Computed: true,
55+
MarkdownDescription: "The email address of the current user.",
56+
},
57+
"is_service_account": schema.BoolAttribute{
58+
Computed: true,
59+
MarkdownDescription: "Whether the current user is a service account.",
60+
},
61+
},
62+
}
63+
}
64+
65+
func (d *dataSourceCurrentUser) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
66+
if req.ProviderData == nil {
67+
return
68+
}
69+
70+
client, ok := req.ProviderData.(ConfiguredClient)
71+
if !ok {
72+
resp.Diagnostics.AddError(
73+
"Unexpected Data Source Configure Type",
74+
fmt.Sprintf("Expected ConfiguredClient, got %T. This is a bug in the tfe provider, so please report it on GitHub.", req.ProviderData),
75+
)
76+
77+
return
78+
}
79+
80+
d.config = client
81+
}
82+
83+
func (d *dataSourceCurrentUser) Read(ctx context.Context, _ datasource.ReadRequest, resp *datasource.ReadResponse) {
84+
tflog.Debug(ctx, "Reading current user")
85+
86+
user, err := d.config.Client.Users.ReadCurrent(ctx)
87+
if err != nil {
88+
resp.Diagnostics.AddError("Unable to read current user", err.Error())
89+
return
90+
}
91+
92+
model := modelCurrentUser{
93+
ID: types.StringValue(user.ID),
94+
Username: types.StringValue(user.Username),
95+
Email: types.StringValue(user.Email),
96+
IsServiceAccount: types.BoolValue(user.IsServiceAccount),
97+
}
98+
99+
tflog.Trace(ctx, "Read current user successfully", map[string]any{
100+
"user_id": user.ID,
101+
"username": user.Username,
102+
"is_service_account": user.IsServiceAccount,
103+
})
104+
105+
diags := resp.State.Set(ctx, &model)
106+
resp.Diagnostics.Append(diags...)
107+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright IBM Corp. 2018, 2025
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package provider
5+
6+
import (
7+
"testing"
8+
9+
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
10+
)
11+
12+
func TestAccCurrentUserDataSource_basic(t *testing.T) {
13+
resourceAddress := "data.tfe_current_user.test"
14+
resource.Test(t, resource.TestCase{
15+
PreCheck: func() { testAccPreCheck(t) },
16+
ProtoV6ProviderFactories: testAccMuxedProviders,
17+
Steps: []resource.TestStep{
18+
{
19+
Config: testAccCurrentUserDataSourceConfig_basic(),
20+
Check: resource.ComposeAggregateTestCheckFunc(
21+
resource.TestCheckResourceAttrSet(resourceAddress, "id"),
22+
resource.TestCheckResourceAttrSet(resourceAddress, "username"),
23+
resource.TestCheckResourceAttrSet(resourceAddress, "email"),
24+
resource.TestCheckResourceAttrSet(resourceAddress, "is_service_account"),
25+
),
26+
},
27+
},
28+
})
29+
}
30+
31+
func testAccCurrentUserDataSourceConfig_basic() string {
32+
return `data "tfe_current_user" "test" {}`
33+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright IBM Corp. 2018, 2025
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package planmodifiers
5+
6+
import (
7+
"context"
8+
9+
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
10+
)
11+
12+
type warnIfNullOnCreateModifier struct {
13+
message string
14+
}
15+
16+
func (m warnIfNullOnCreateModifier) Description(ctx context.Context) string {
17+
return "Warning that the attribute value is null during resource creation"
18+
}
19+
20+
func (m warnIfNullOnCreateModifier) MarkdownDescription(ctx context.Context) string {
21+
return m.Description(ctx)
22+
}
23+
24+
func (m warnIfNullOnCreateModifier) PlanModifyString(ctx context.Context, req planmodifier.StringRequest, resp *planmodifier.StringResponse) {
25+
if req.State.Raw.IsNull() && req.ConfigValue.IsNull() {
26+
resp.Diagnostics.AddWarning(
27+
m.message,
28+
"",
29+
)
30+
}
31+
}
32+
33+
func WarnIfNullOnCreate(message string) planmodifier.String {
34+
return warnIfNullOnCreateModifier{
35+
message: message,
36+
}
37+
}

internal/provider/provider_next.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ func (p *frameworkProvider) Actions(ctx context.Context) []func() action.Action
143143

144144
func (p *frameworkProvider) DataSources(ctx context.Context) []func() datasource.DataSource {
145145
return []func() datasource.DataSource{
146+
NewCurrentUserDataSource,
146147
NewHYOKCustomerKeyVersionDataSource,
147148
NewHYOKEncryptedDataKeyDataSource,
148149
NewNoCodeModuleDataSource,

internal/provider/resource_tfe_audit_trail_token.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
2222
"github.com/hashicorp/terraform-plugin-framework/types"
2323
"github.com/hashicorp/terraform-plugin-log/tflog"
24+
"github.com/hashicorp/terraform-provider-tfe/internal/provider/planmodifiers"
2425
)
2526

2627
type resourceAuditTrailToken struct {
@@ -99,8 +100,13 @@ func (r *resourceAuditTrailToken) Schema(ctx context.Context, req resource.Schem
99100
Description: "The time when the audit trail token will expire. This must be a valid ISO8601 timestamp.",
100101
CustomType: timetypes.RFC3339Type{},
101102
Optional: true,
103+
Computed: true,
102104
PlanModifiers: []planmodifier.String{
103105
stringplanmodifier.RequiresReplace(),
106+
stringplanmodifier.UseStateForUnknown(),
107+
planmodifiers.WarnIfNullOnCreate(
108+
"Audit Trail Token expiration null values defaults to 24 months",
109+
),
104110
},
105111
},
106112
"organization": schema.StringAttribute{

internal/provider/resource_tfe_audit_trail_token_test.go

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,37 @@ func TestAccTFEAuditTrailToken_withInvalidExpiry(t *testing.T) {
163163
})
164164
}
165165

166+
func TestAccTFEAuditTrailToken_withBlankExpiry(t *testing.T) {
167+
skipUnlessBeta(t)
168+
token := &tfe.OrganizationToken{}
169+
170+
tfeClient, err := getClientUsingEnv()
171+
if err != nil {
172+
t.Fatal(err)
173+
}
174+
org, orgCleanup := createBusinessOrganization(t, tfeClient)
175+
t.Cleanup(orgCleanup)
176+
177+
resource.Test(t, resource.TestCase{
178+
PreCheck: func() { testAccPreCheck(t) },
179+
ProtoV6ProviderFactories: testAccMuxedProviders,
180+
CheckDestroy: testAccCheckTFEAuditTrailTokenDestroy,
181+
Steps: []resource.TestStep{
182+
{
183+
Config: testAccTFEAuditTrailToken_withBlankExpiry(org.Name),
184+
Check: resource.ComposeTestCheckFunc(
185+
testAccCheckTFEAuditTrailTokenExists(
186+
"tfe_audit_trail_token.foobar", token),
187+
resource.TestCheckResourceAttr(
188+
"tfe_audit_trail_token.foobar", "organization", org.Name),
189+
resource.TestCheckResourceAttrSet(
190+
"tfe_audit_trail_token.foobar", "expired_at"),
191+
),
192+
},
193+
},
194+
})
195+
}
196+
166197
func TestAccTFEAuditTrailToken_import(t *testing.T) {
167198
tfeClient, err := getClientUsingEnv()
168199
if err != nil {
@@ -281,7 +312,6 @@ func testAccTFEAuditTrailToken_withBlankExpiry(orgName string) string {
281312
return fmt.Sprintf(`
282313
resource "tfe_audit_trail_token" "foobar" {
283314
organization = "%s"
284-
expired_at = ""
285315
}`, orgName)
286316
}
287317

0 commit comments

Comments
 (0)