Skip to content

Commit f314c31

Browse files
committed
chore: add missing template data source fields
1 parent ef286de commit f314c31

File tree

2 files changed

+108
-7
lines changed

2 files changed

+108
-7
lines changed

internal/provider/template_data_source.go

Lines changed: 83 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"github.com/coder/coder/v2/codersdk"
88
"github.com/google/uuid"
99
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
10+
"github.com/hashicorp/terraform-plugin-framework/attr"
1011
"github.com/hashicorp/terraform-plugin-framework/datasource"
1112
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
1213
"github.com/hashicorp/terraform-plugin-framework/path"
@@ -42,10 +43,10 @@ type TemplateDataSourceModel struct {
4243
DeprecationMessage types.String `tfsdk:"deprecation_message"`
4344
Icon types.String `tfsdk:"icon"`
4445

45-
DefaultTTLMillis types.Int64 `tfsdk:"default_ttl_ms"`
46-
ActivityBumpMillis types.Int64 `tfsdk:"activity_bump_ms"`
47-
// TODO: AutostopRequirement
48-
// TODO: AutostartRequirement
46+
DefaultTTLMillis types.Int64 `tfsdk:"default_ttl_ms"`
47+
ActivityBumpMillis types.Int64 `tfsdk:"activity_bump_ms"`
48+
AutostopRequirement types.Object `tfsdk:"auto_stop_requirement"`
49+
AutostartPermittedDaysOfWeek types.Set `tfsdk:"auto_start_permitted_days_of_week"`
4950

5051
AllowUserAutostart types.Bool `tfsdk:"allow_user_autostart"`
5152
AllowUserAutostop types.Bool `tfsdk:"allow_user_autostop"`
@@ -55,14 +56,14 @@ type TemplateDataSourceModel struct {
5556
TimeTilDormantMillis types.Int64 `tfsdk:"time_til_dormant_ms"`
5657
TimeTilDormantAutoDeleteMillis types.Int64 `tfsdk:"time_til_dormant_autodelete_ms"`
5758

58-
RequireActiveVersion types.Bool `tfsdk:"require_active_version"`
59-
// TODO: MaxPortShareLevel
59+
RequireActiveVersion types.Bool `tfsdk:"require_active_version"`
60+
MaxPortShareLevel types.String `tfsdk:"max_port_share_level"`
6061

6162
CreatedByUserID UUID `tfsdk:"created_by_user_id"`
6263
CreatedAt types.Int64 `tfsdk:"created_at"` // Unix timestamp
6364
UpdatedAt types.Int64 `tfsdk:"updated_at"` // Unix timestamp
6465

65-
// TODO: ACL-related stuff
66+
ACL types.Object `tfsdk:"acl"`
6667
}
6768

6869
func (d *TemplateDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
@@ -134,6 +135,27 @@ func (d *TemplateDataSource) Schema(ctx context.Context, req datasource.SchemaRe
134135
MarkdownDescription: "Duration to bump the deadline of a workspace when it receives activity.",
135136
Computed: true,
136137
},
138+
"auto_stop_requirement": schema.SingleNestedAttribute{
139+
MarkdownDescription: "The auto-stop requirement for all workspaces created from this template.",
140+
Computed: true,
141+
Attributes: map[string]schema.Attribute{
142+
"days_of_week": schema.SetAttribute{
143+
MarkdownDescription: "List of days of the week on which restarts are required. Restarts happen within the user's quiet hours (in their configured timezone). If no days are specified, restarts are not required.",
144+
Computed: true,
145+
ElementType: types.StringType,
146+
},
147+
"weeks": schema.Int64Attribute{
148+
MarkdownDescription: "Weeks is the number of weeks between required restarts. Weeks are synced across all workspaces (and Coder deployments) using modulo math on a hardcoded epoch week of January 2nd, 2023 (the first Monday of 2023). Values of 0 or 1 indicate weekly restarts. Values of 2 indicate fortnightly restarts, etc.",
149+
Optional: true,
150+
Computed: true,
151+
},
152+
},
153+
},
154+
"auto_start_permitted_days_of_week": schema.SetAttribute{
155+
MarkdownDescription: "List of days of the week in which autostart is allowed to happen, for all workspaces created from this template. Defaults to all days. If no days are specified, autostart is not allowed.",
156+
Computed: true,
157+
ElementType: types.StringType,
158+
},
137159
"allow_user_autostart": schema.BoolAttribute{
138160
MarkdownDescription: "Whether users can autostart workspaces created from the template.",
139161
Computed: true,
@@ -162,6 +184,10 @@ func (d *TemplateDataSource) Schema(ctx context.Context, req datasource.SchemaRe
162184
MarkdownDescription: "Whether workspaces created from the template must be up-to-date on the latest active version.",
163185
Computed: true,
164186
},
187+
"max_port_share_level": schema.StringAttribute{
188+
MarkdownDescription: "The maximum port share level for workspaces created from the template.",
189+
Computed: true,
190+
},
165191
"created_by_user_id": schema.StringAttribute{
166192
MarkdownDescription: "ID of the user who created the template.",
167193
CustomType: UUIDType,
@@ -175,6 +201,14 @@ func (d *TemplateDataSource) Schema(ctx context.Context, req datasource.SchemaRe
175201
MarkdownDescription: "Unix timestamp of when the template was last updated.",
176202
Computed: true,
177203
},
204+
"acl": schema.SingleNestedAttribute{
205+
MarkdownDescription: "(Enterprise) Access control list for the template. If null, ACL policies will not be added, removed, or inspected by Terraform.",
206+
Computed: true,
207+
Attributes: map[string]schema.Attribute{
208+
"users": computedPermissionAttribute,
209+
"groups": computedPermissionAttribute,
210+
},
211+
},
178212
},
179213
}
180214
}
@@ -244,6 +278,33 @@ func (d *TemplateDataSource) Read(ctx context.Context, req datasource.ReadReques
244278
return
245279
}
246280

281+
acl, err := client.TemplateACL(ctx, template.ID)
282+
if err != nil {
283+
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to get template ACL: %s", err))
284+
return
285+
}
286+
tfACL := convertResponseToACL(acl)
287+
aclObj, diag := types.ObjectValueFrom(ctx, aclTypeAttr, tfACL)
288+
if diag.HasError() {
289+
resp.Diagnostics.Append(diag...)
290+
return
291+
}
292+
293+
asrObj, diag := types.ObjectValueFrom(ctx, autostopRequirementTypeAttr, AutostopRequirement{
294+
DaysOfWeek: template.AutostopRequirement.DaysOfWeek,
295+
Weeks: template.AutostopRequirement.Weeks,
296+
})
297+
resp.Diagnostics.Append(diag...)
298+
if resp.Diagnostics.HasError() {
299+
return
300+
}
301+
autoStartDays := make([]attr.Value, 0, len(template.AutostartRequirement.DaysOfWeek))
302+
for _, day := range template.AutostartRequirement.DaysOfWeek {
303+
autoStartDays = append(autoStartDays, types.StringValue(day))
304+
}
305+
data.ACL = aclObj
306+
data.AutostartPermittedDaysOfWeek = types.SetValueMust(types.StringType, autoStartDays)
307+
data.AutostopRequirement = asrObj
247308
data.OrganizationID = UUIDValue(template.OrganizationID)
248309
data.ID = UUIDValue(template.ID)
249310
data.Name = types.StringValue(template.Name)
@@ -270,3 +331,18 @@ func (d *TemplateDataSource) Read(ctx context.Context, req datasource.ReadReques
270331
// Save data into Terraform state
271332
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
272333
}
334+
335+
// computedPermissionAttribute is the attribute schema for a computed instance of `[]Permission`.
336+
var computedPermissionAttribute = schema.SetNestedAttribute{
337+
Computed: true,
338+
NestedObject: schema.NestedAttributeObject{
339+
Attributes: map[string]schema.Attribute{
340+
"id": schema.StringAttribute{
341+
Computed: true,
342+
},
343+
"role": schema.StringAttribute{
344+
Computed: true,
345+
},
346+
},
347+
},
348+
}

internal/provider/template_data_source_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,16 @@ func TestAccTemplateDataSource(t *testing.T) {
9999
})
100100
require.NoError(t, err)
101101

102+
err = client.UpdateTemplateACL(ctx, tpl.ID, codersdk.UpdateTemplateACL{
103+
UserPerms: map[string]codersdk.TemplateRole{
104+
firstUser.ID.String(): codersdk.TemplateRoleAdmin,
105+
},
106+
GroupPerms: map[string]codersdk.TemplateRole{
107+
firstUser.OrganizationIDs[0].String(): codersdk.TemplateRoleUse,
108+
},
109+
})
110+
require.NoError(t, err)
111+
102112
checkFn := resource.ComposeAggregateTestCheckFunc(
103113
resource.TestCheckResourceAttr("data.coderd_template.test", "organization_id", tpl.OrganizationID.String()),
104114
resource.TestCheckResourceAttr("data.coderd_template.test", "id", tpl.ID.String()),
@@ -112,16 +122,31 @@ func TestAccTemplateDataSource(t *testing.T) {
112122
resource.TestCheckResourceAttr("data.coderd_template.test", "icon", tpl.Icon),
113123
resource.TestCheckResourceAttr("data.coderd_template.test", "default_ttl_ms", strconv.FormatInt(tpl.DefaultTTLMillis, 10)),
114124
resource.TestCheckResourceAttr("data.coderd_template.test", "activity_bump_ms", strconv.FormatInt(tpl.ActivityBumpMillis, 10)),
125+
resource.TestCheckResourceAttr("data.coderd_template.test", "auto_stop_requirement.days_of_week.#", strconv.FormatInt(int64(len(tpl.AutostopRequirement.DaysOfWeek)), 10)),
126+
resource.TestCheckResourceAttr("data.coderd_template.test", "auto_stop_requirement.weeks", strconv.FormatInt(tpl.AutostopRequirement.Weeks, 10)),
127+
resource.TestCheckResourceAttr("data.coderd_template.test", "auto_start_permitted_days_of_week.#", strconv.FormatInt(int64(len(tpl.AutostartRequirement.DaysOfWeek)), 10)),
128+
resource.TestCheckResourceAttr("data.coderd_template.test", "allow_user_cancel_workspace_jobs", "true"),
115129
resource.TestCheckResourceAttr("data.coderd_template.test", "allow_user_autostart", strconv.FormatBool(tpl.AllowUserAutostart)),
116130
resource.TestCheckResourceAttr("data.coderd_template.test", "allow_user_autostop", strconv.FormatBool(tpl.AllowUserAutostop)),
117131
resource.TestCheckResourceAttr("data.coderd_template.test", "allow_user_cancel_workspace_jobs", strconv.FormatBool(tpl.AllowUserCancelWorkspaceJobs)),
118132
resource.TestCheckResourceAttr("data.coderd_template.test", "failure_ttl_ms", strconv.FormatInt(tpl.FailureTTLMillis, 10)),
119133
resource.TestCheckResourceAttr("data.coderd_template.test", "time_til_dormant_ms", strconv.FormatInt(tpl.TimeTilDormantMillis, 10)),
120134
resource.TestCheckResourceAttr("data.coderd_template.test", "time_til_dormant_autodelete_ms", strconv.FormatInt(tpl.TimeTilDormantAutoDeleteMillis, 10)),
121135
resource.TestCheckResourceAttr("data.coderd_template.test", "require_active_version", strconv.FormatBool(tpl.RequireActiveVersion)),
136+
resource.TestCheckResourceAttr("data.coderd_template.test", "max_port_share_level", string(tpl.MaxPortShareLevel)),
122137
resource.TestCheckResourceAttr("data.coderd_template.test", "created_by_user_id", firstUser.ID.String()),
123138
resource.TestCheckResourceAttr("data.coderd_template.test", "created_at", strconv.Itoa(int(tpl.CreatedAt.Unix()))),
124139
resource.TestCheckResourceAttr("data.coderd_template.test", "updated_at", strconv.Itoa(int(tpl.UpdatedAt.Unix()))),
140+
resource.TestCheckResourceAttr("data.coderd_template.test", "acl.groups.#", "1"),
141+
resource.TestCheckResourceAttr("data.coderd_template.test", "acl.users.#", "1"),
142+
resource.TestMatchTypeSetElemNestedAttrs("data.coderd_template.test", "acl.groups.*", map[string]*regexp.Regexp{
143+
"id": regexp.MustCompile(firstUser.OrganizationIDs[0].String()),
144+
"role": regexp.MustCompile("^use$"),
145+
}),
146+
resource.TestMatchTypeSetElemNestedAttrs("data.coderd_template.test", "acl.users.*", map[string]*regexp.Regexp{
147+
"id": regexp.MustCompile(firstUser.ID.String()),
148+
"role": regexp.MustCompile("^admin$"),
149+
}),
125150
)
126151

127152
t.Run("TemplateByOrgAndNameOK", func(t *testing.T) {

0 commit comments

Comments
 (0)