Skip to content

Commit 44c4e1b

Browse files
committed
chore: add uuid terraform type
1 parent 3e8547b commit 44c4e1b

File tree

9 files changed

+322
-134
lines changed

9 files changed

+322
-134
lines changed

internal/provider/group_data_source.go

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"fmt"
66

77
"github.com/coder/coder/v2/codersdk"
8-
"github.com/google/uuid"
98
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
109
"github.com/hashicorp/terraform-plugin-framework/datasource"
1110
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
@@ -29,9 +28,9 @@ type GroupDataSource struct {
2928
// GroupDataSourceModel describes the data source data model.
3029
type GroupDataSourceModel struct {
3130
// ID or name and organization ID must be set
32-
ID types.String `tfsdk:"id"`
31+
ID UUID `tfsdk:"id"`
3332
Name types.String `tfsdk:"name"`
34-
OrganizationID types.String `tfsdk:"organization_id"`
33+
OrganizationID UUID `tfsdk:"organization_id"`
3534

3635
DisplayName types.String `tfsdk:"display_name"`
3736
AvatarURL types.String `tfsdk:"avatar_url"`
@@ -41,7 +40,7 @@ type GroupDataSourceModel struct {
4140
}
4241

4342
type Member struct {
44-
ID types.String `tfsdk:"id"`
43+
ID UUID `tfsdk:"id"`
4544
Username types.String `tfsdk:"username"`
4645
Email types.String `tfsdk:"email"`
4746
CreatedAt types.Int64 `tfsdk:"created_at"`
@@ -64,6 +63,7 @@ func (d *GroupDataSource) Schema(ctx context.Context, req datasource.SchemaReque
6463
MarkdownDescription: "The ID of the group to retrieve. This field will be populated if a name and organization ID is supplied.",
6564
Optional: true,
6665
Computed: true,
66+
CustomType: UUIDType,
6767
Validators: []validator.String{
6868
stringvalidator.AtLeastOneOf(path.Expressions{
6969
path.MatchRoot("name"),
@@ -78,6 +78,7 @@ func (d *GroupDataSource) Schema(ctx context.Context, req datasource.SchemaReque
7878
},
7979
"organization_id": schema.StringAttribute{
8080
MarkdownDescription: "The organization ID that the group belongs to. This field will be populated if an ID is supplied. Defaults to the provider default organization ID.",
81+
CustomType: UUIDType,
8182
Optional: true,
8283
Computed: true,
8384
},
@@ -101,7 +102,8 @@ func (d *GroupDataSource) Schema(ctx context.Context, req datasource.SchemaReque
101102
NestedObject: schema.NestedAttributeObject{
102103
Attributes: map[string]schema.Attribute{
103104
"id": schema.StringAttribute{
104-
Computed: true,
105+
CustomType: UUIDType,
106+
Computed: true,
105107
},
106108
"username": schema.StringAttribute{
107109
Computed: true,
@@ -169,36 +171,27 @@ func (d *GroupDataSource) Read(ctx context.Context, req datasource.ReadRequest,
169171
client := d.data.Client
170172

171173
if data.OrganizationID.IsNull() {
172-
data.OrganizationID = types.StringValue(d.data.DefaultOrganizationID)
174+
data.OrganizationID = UUIDValue(d.data.DefaultOrganizationID)
173175
}
174176

175177
var group codersdk.Group
178+
var err error
176179
if !data.ID.IsNull() {
177-
groupID, err := uuid.Parse(data.ID.ValueString())
178-
if err != nil {
179-
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to parse supplied group ID as UUID, got error: %s", err))
180-
return
181-
}
182-
180+
groupID := data.ID.ValueUUID()
183181
group, err = client.Group(ctx, groupID)
184182
if err != nil {
185183
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to get group by ID, got error: %s", err))
186184
return
187185
}
188186
data.Name = types.StringValue(group.Name)
189-
data.OrganizationID = types.StringValue(group.OrganizationID.String())
187+
data.OrganizationID = UUIDValue(group.OrganizationID)
190188
} else {
191-
orgID, err := uuid.Parse(data.OrganizationID.ValueString())
192-
if err != nil {
193-
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to parse supplied organization ID as UUID, got error: %s", err))
194-
return
195-
}
196-
group, err = client.GroupByOrgAndName(ctx, orgID, data.Name.ValueString())
189+
group, err = client.GroupByOrgAndName(ctx, data.OrganizationID.ValueUUID(), data.Name.ValueString())
197190
if err != nil {
198191
resp.Diagnostics.AddError("Failed to get group by name and org ID", err.Error())
199192
return
200193
}
201-
data.ID = types.StringValue(group.ID.String())
194+
data.ID = UUIDValue(group.ID)
202195
}
203196

204197
data.DisplayName = types.StringValue(group.DisplayName)
@@ -207,7 +200,7 @@ func (d *GroupDataSource) Read(ctx context.Context, req datasource.ReadRequest,
207200
members := make([]Member, 0, len(group.Members))
208201
for _, member := range group.Members {
209202
members = append(members, Member{
210-
ID: types.StringValue(member.ID.String()),
203+
ID: UUIDValue(member.ID),
211204
Username: types.StringValue(member.Username),
212205
Email: types.StringValue(member.Email),
213206
CreatedAt: types.Int64Value(member.CreatedAt.Unix()),

internal/provider/group_resource.go

Lines changed: 16 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,13 @@ type GroupResource struct {
3535

3636
// GroupResourceModel describes the resource data model.
3737
type GroupResourceModel struct {
38-
ID types.String `tfsdk:"id"`
38+
ID UUID `tfsdk:"id"`
3939

4040
Name types.String `tfsdk:"name"`
4141
DisplayName types.String `tfsdk:"display_name"`
4242
AvatarURL types.String `tfsdk:"avatar_url"`
4343
QuotaAllowance types.Int32 `tfsdk:"quota_allowance"`
44-
OrganizationID types.String `tfsdk:"organization_id"`
44+
OrganizationID UUID `tfsdk:"organization_id"`
4545
Members types.Set `tfsdk:"members"`
4646
}
4747

@@ -56,6 +56,7 @@ func (r *GroupResource) Schema(ctx context.Context, req resource.SchemaRequest,
5656
Attributes: map[string]schema.Attribute{
5757
"id": schema.StringAttribute{
5858
MarkdownDescription: "Group ID.",
59+
CustomType: UUIDType,
5960
Computed: true,
6061
PlanModifiers: []planmodifier.String{
6162
stringplanmodifier.UseStateForUnknown(),
@@ -84,6 +85,7 @@ func (r *GroupResource) Schema(ctx context.Context, req resource.SchemaRequest,
8485
},
8586
"organization_id": schema.StringAttribute{
8687
MarkdownDescription: "The organization ID that the group belongs to. Defaults to the provider default organization ID.",
88+
CustomType: UUIDType,
8789
Optional: true,
8890
Computed: true,
8991
PlanModifiers: []planmodifier.String{
@@ -92,7 +94,7 @@ func (r *GroupResource) Schema(ctx context.Context, req resource.SchemaRequest,
9294
},
9395
"members": schema.SetAttribute{
9496
MarkdownDescription: "Members of the group, by ID. If null, members will not be added or removed.",
95-
ElementType: types.StringType,
97+
ElementType: UUIDType,
9698
Optional: true,
9799
},
98100
},
@@ -132,14 +134,10 @@ func (r *GroupResource) Create(ctx context.Context, req resource.CreateRequest,
132134
client := r.data.Client
133135

134136
if data.OrganizationID.IsUnknown() {
135-
data.OrganizationID = types.StringValue(r.data.DefaultOrganizationID)
137+
data.OrganizationID = UUIDValue(r.data.DefaultOrganizationID)
136138
}
137139

138-
orgID, err := uuid.Parse(data.OrganizationID.ValueString())
139-
if err != nil {
140-
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to parse supplied organization ID as UUID, got error: %s", err))
141-
return
142-
}
140+
orgID := data.OrganizationID.ValueUUID()
143141

144142
displayName := data.Name.ValueString()
145143
if data.DisplayName.ValueString() != "" {
@@ -160,7 +158,7 @@ func (r *GroupResource) Create(ctx context.Context, req resource.CreateRequest,
160158
tflog.Trace(ctx, "successfully created group", map[string]any{
161159
"id": group.ID.String(),
162160
})
163-
data.ID = types.StringValue(group.ID.String())
161+
data.ID = UUIDValue(group.ID)
164162
data.DisplayName = types.StringValue(group.DisplayName)
165163

166164
tflog.Trace(ctx, "setting group members")
@@ -196,11 +194,7 @@ func (r *GroupResource) Read(ctx context.Context, req resource.ReadRequest, resp
196194

197195
client := r.data.Client
198196

199-
groupID, err := uuid.Parse(data.ID.ValueString())
200-
if err != nil {
201-
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to parse supplied group ID as UUID, got error: %s", err))
202-
return
203-
}
197+
groupID := data.ID.ValueUUID()
204198

205199
group, err := client.Group(ctx, groupID)
206200
if err != nil {
@@ -212,13 +206,13 @@ func (r *GroupResource) Read(ctx context.Context, req resource.ReadRequest, resp
212206
data.DisplayName = types.StringValue(group.DisplayName)
213207
data.AvatarURL = types.StringValue(group.AvatarURL)
214208
data.QuotaAllowance = types.Int32Value(int32(group.QuotaAllowance))
215-
data.OrganizationID = types.StringValue(group.OrganizationID.String())
209+
data.OrganizationID = UUIDValue(group.OrganizationID)
216210
if !data.Members.IsNull() {
217211
members := make([]attr.Value, 0, len(group.Members))
218212
for _, member := range group.Members {
219-
members = append(members, types.StringValue(member.ID.String()))
213+
members = append(members, UUIDValue(member.ID))
220214
}
221-
data.Members = types.SetValueMust(types.StringType, members)
215+
data.Members = types.SetValueMust(UUIDType, members)
222216
}
223217

224218
// Save updated data into Terraform state
@@ -237,13 +231,9 @@ func (r *GroupResource) Update(ctx context.Context, req resource.UpdateRequest,
237231

238232
client := r.data.Client
239233
if data.OrganizationID.IsUnknown() {
240-
data.OrganizationID = types.StringValue(r.data.DefaultOrganizationID)
241-
}
242-
groupID, err := uuid.Parse(data.ID.ValueString())
243-
if err != nil {
244-
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to parse supplied group ID as UUID, got error: %s", err))
245-
return
234+
data.OrganizationID = UUIDValue(r.data.DefaultOrganizationID)
246235
}
236+
groupID := data.ID.ValueUUID()
247237

248238
group, err := client.Group(ctx, groupID)
249239
if err != nil {
@@ -301,14 +291,10 @@ func (r *GroupResource) Delete(ctx context.Context, req resource.DeleteRequest,
301291
}
302292

303293
client := r.data.Client
304-
groupID, err := uuid.Parse(data.ID.ValueString())
305-
if err != nil {
306-
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to parse supplied group ID as UUID, got error: %s", err))
307-
return
308-
}
294+
groupID := data.ID.ValueUUID()
309295

310296
tflog.Trace(ctx, "deleting group")
311-
err = client.DeleteGroup(ctx, groupID)
297+
err := client.DeleteGroup(ctx, groupID)
312298
if err != nil {
313299
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to delete group, got error: %s", err))
314300
return

internal/provider/organization_data_source.go

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"fmt"
66

77
"github.com/coder/coder/v2/codersdk"
8-
"github.com/google/uuid"
98
"github.com/hashicorp/terraform-plugin-framework-validators/datasourcevalidator"
109
"github.com/hashicorp/terraform-plugin-framework/attr"
1110
"github.com/hashicorp/terraform-plugin-framework/datasource"
@@ -30,7 +29,7 @@ type OrganizationDataSource struct {
3029
// OrganizationDataSourceModel describes the data source data model.
3130
type OrganizationDataSourceModel struct {
3231
// Exactly one of ID, IsDefault, or Name must be set.
33-
ID types.String `tfsdk:"id"`
32+
ID UUID `tfsdk:"id"`
3433
IsDefault types.Bool `tfsdk:"is_default"`
3534
Name types.String `tfsdk:"name"`
3635

@@ -52,6 +51,7 @@ func (d *OrganizationDataSource) Schema(ctx context.Context, req datasource.Sche
5251
Attributes: map[string]schema.Attribute{
5352
"id": schema.StringAttribute{
5453
MarkdownDescription: "The ID of the organization to retrieve. This field will be populated if the organization is found by name, or if the default organization is requested.",
54+
CustomType: UUIDType,
5555
Optional: true,
5656
Computed: true,
5757
},
@@ -77,7 +77,7 @@ func (d *OrganizationDataSource) Schema(ctx context.Context, req datasource.Sche
7777
"members": schema.SetAttribute{
7878
MarkdownDescription: "Members of the organization, by ID",
7979
Computed: true,
80-
ElementType: types.StringType,
80+
ElementType: UUIDType,
8181
},
8282
},
8383
}
@@ -116,23 +116,19 @@ func (d *OrganizationDataSource) Read(ctx context.Context, req datasource.ReadRe
116116
client := d.data.Client
117117

118118
var org codersdk.Organization
119+
var err error
119120
if !data.ID.IsNull() { // By ID
120-
orgID, err := uuid.Parse(data.ID.ValueString())
121-
if err != nil {
122-
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to parse supplied ID as UUID, got error: %s", err))
123-
return
124-
}
121+
orgID := data.ID.ValueUUID()
125122
org, err = client.Organization(ctx, orgID)
126123
if err != nil {
127124
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to get organization by ID, got error: %s", err))
128125
return
129126
}
130-
if org.ID.String() != data.ID.ValueString() {
127+
if org.ID != data.ID.ValueUUID() {
131128
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Organization ID %s does not match requested ID %s", org.ID, data.ID))
132129
return
133130
}
134131
} else if data.IsDefault.ValueBool() { // Get Default
135-
var err error
136132
org, err = client.OrganizationByName(ctx, "default")
137133
if err != nil {
138134
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to get default organization, got error: %s", err))
@@ -143,7 +139,6 @@ func (d *OrganizationDataSource) Read(ctx context.Context, req datasource.ReadRe
143139
return
144140
}
145141
} else { // By Name
146-
var err error
147142
org, err = client.OrganizationByName(ctx, data.Name.ValueString())
148143
if err != nil {
149144
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to get organization by name, got error: %s", err))
@@ -154,7 +149,7 @@ func (d *OrganizationDataSource) Read(ctx context.Context, req datasource.ReadRe
154149
return
155150
}
156151
}
157-
data.ID = types.StringValue(org.ID.String())
152+
data.ID = UUIDValue(org.ID)
158153
data.Name = types.StringValue(org.Name)
159154
data.IsDefault = types.BoolValue(org.IsDefault)
160155
data.CreatedAt = types.Int64Value(org.CreatedAt.Unix())
@@ -166,9 +161,9 @@ func (d *OrganizationDataSource) Read(ctx context.Context, req datasource.ReadRe
166161
}
167162
memberIDs := make([]attr.Value, 0, len(members))
168163
for _, member := range members {
169-
memberIDs = append(memberIDs, types.StringValue(member.UserID.String()))
164+
memberIDs = append(memberIDs, UUIDValue(member.UserID))
170165
}
171-
data.Members = types.SetValueMust(types.StringType, memberIDs)
166+
data.Members = types.SetValueMust(UUIDType, memberIDs)
172167

173168
// Save data into Terraform state
174169
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)

internal/provider/provider.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"strings"
88

99
"cdr.dev/slog"
10+
"github.com/google/uuid"
1011
"github.com/hashicorp/terraform-plugin-framework/datasource"
1112
"github.com/hashicorp/terraform-plugin-framework/function"
1213
"github.com/hashicorp/terraform-plugin-framework/provider"
@@ -31,18 +32,16 @@ type CoderdProvider struct {
3132
}
3233

3334
type CoderdProviderData struct {
34-
Client *codersdk.Client
35-
// TODO(ethanndickson): We should use a custom TFPF type for UUIDs everywhere
36-
// possible, instead of `string` and `types.String`.
37-
DefaultOrganizationID string
35+
Client *codersdk.Client
36+
DefaultOrganizationID uuid.UUID
3837
}
3938

4039
// CoderdProviderModel describes the provider data model.
4140
type CoderdProviderModel struct {
4241
URL types.String `tfsdk:"url"`
4342
Token types.String `tfsdk:"token"`
4443

45-
DefaultOrganizationID types.String `tfsdk:"default_organization_id"`
44+
DefaultOrganizationID UUID `tfsdk:"default_organization_id"`
4645
}
4746

4847
func (p *CoderdProvider) Metadata(ctx context.Context, req provider.MetadataRequest, resp *provider.MetadataResponse) {
@@ -63,6 +62,7 @@ func (p *CoderdProvider) Schema(ctx context.Context, req provider.SchemaRequest,
6362
},
6463
"default_organization_id": schema.StringAttribute{
6564
MarkdownDescription: "Default organization ID to use when creating resources. Defaults to the first organization the token has access to.",
65+
CustomType: UUIDType,
6666
Optional: true,
6767
},
6868
},
@@ -109,11 +109,11 @@ func (p *CoderdProvider) Configure(ctx context.Context, req provider.ConfigureRe
109109
resp.Diagnostics.AddError("default_organization_id", "failed to get default organization ID: "+err.Error())
110110
return
111111
}
112-
data.DefaultOrganizationID = types.StringValue(user.OrganizationIDs[0].String())
112+
data.DefaultOrganizationID = UUIDValue(user.OrganizationIDs[0])
113113
}
114114
providerData := &CoderdProviderData{
115115
Client: client,
116-
DefaultOrganizationID: data.DefaultOrganizationID.ValueString(),
116+
DefaultOrganizationID: data.DefaultOrganizationID.ValueUUID(),
117117
}
118118
resp.DataSourceData = providerData
119119
resp.ResourceData = providerData

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy