Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit bcba9b7

Browse files
authored
feat: add template data source (#46)
1 parent d157e1d commit bcba9b7

File tree

5 files changed

+561
-2
lines changed

5 files changed

+561
-2
lines changed

docs/data-sources/template.md

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "coderd_template Data Source - coderd"
4+
subcategory: ""
5+
description: |-
6+
An existing template on the coder deployment
7+
---
8+
9+
# coderd_template (Data Source)
10+
11+
An existing template on the coder deployment
12+
13+
14+
15+
<!-- schema generated by tfplugindocs -->
16+
## Schema
17+
18+
### Optional
19+
20+
- `id` (String) The ID of the template to retrieve. This field will be populated if a template name is supplied.
21+
- `name` (String) The name of the template to retrieve. This field will be populated if an ID is supplied.
22+
- `organization_id` (String) ID of the organization the template is associated with.
23+
24+
### Read-Only
25+
26+
- `active_user_count` (Number) Number of active users using the template.
27+
- `active_version_id` (String) ID of the active version of the template.
28+
- `activity_bump_ms` (Number) Duration to bump the deadline of a workspace when it receives activity.
29+
- `allow_user_autostart` (Boolean) Whether users can autostart workspaces created from the template.
30+
- `allow_user_autostop` (Boolean) Whether users can customize autostop behavior for workspaces created from the template.
31+
- `allow_user_cancel_workspace_jobs` (Boolean) Whether users can cancel jobs in workspaces created from the template.
32+
- `created_at` (Number) Unix timestamp of when the template was created.
33+
- `created_by_user_id` (String) ID of the user who created the template.
34+
- `default_ttl_ms` (Number) Default time-to-live for workspaces created from the template.
35+
- `deprecated` (Boolean) Whether the template is deprecated.
36+
- `deprecation_message` (String) Message to display when the template is deprecated.
37+
- `description` (String) Description of the template.
38+
- `display_name` (String) Display name of the template.
39+
- `failure_ttl_ms` (Number) Automatic cleanup TTL for failed workspace builds.
40+
- `icon` (String) URL of the template's icon.
41+
- `require_active_version` (Boolean) Whether workspaces created from the template must be up-to-datae on the latest active version.
42+
- `time_til_dormant_autodelete_ms` (Number) Duration of inactivity after the workspace becomes dormant before a workspace is automatically deleted.
43+
- `time_til_dormant_ms` (Number) Duration of inactivity before a workspace is considered dormant.
44+
- `updated_at` (Number) Unix timestamp of when the template was last updated.

integration/template-test/main.tf

+6-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ resource "coderd_user" "ethan" {
1717
suspended = false
1818
}
1919

20-
2120
data "coderd_organization" "default" {
2221
is_default = true
2322
}
@@ -64,4 +63,9 @@ resource "coderd_template" "sample" {
6463
]
6564
}
6665
]
67-
}
66+
}
67+
68+
data "coderd_template" "sample" {
69+
organization_id = data.coderd_organization.default.id
70+
name = coderd_template.sample.name
71+
}

internal/provider/provider.go

+1
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ func (p *CoderdProvider) DataSources(ctx context.Context) []func() datasource.Da
132132
NewGroupDataSource,
133133
NewUserDataSource,
134134
NewOrganizationDataSource,
135+
NewTemplateDataSource,
135136
}
136137
}
137138

+272
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
package provider
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/coder/coder/v2/codersdk"
8+
"github.com/google/uuid"
9+
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
10+
"github.com/hashicorp/terraform-plugin-framework/datasource"
11+
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
12+
"github.com/hashicorp/terraform-plugin-framework/path"
13+
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
14+
"github.com/hashicorp/terraform-plugin-framework/types"
15+
)
16+
17+
// Ensure provider defined types fully satisfy framework interfaces.
18+
var _ datasource.DataSource = &TemplateDataSource{}
19+
20+
func NewTemplateDataSource() datasource.DataSource {
21+
return &TemplateDataSource{}
22+
}
23+
24+
// TemplateDataSource defines the data source implementation.
25+
type TemplateDataSource struct {
26+
data *CoderdProviderData
27+
}
28+
29+
// TemplateDataSourceModel describes the data source data model.
30+
type TemplateDataSourceModel struct {
31+
// ((Organization and Name) or ID) must be set
32+
OrganizationID UUID `tfsdk:"organization_id"`
33+
ID UUID `tfsdk:"id"`
34+
Name types.String `tfsdk:"name"`
35+
36+
DisplayName types.String `tfsdk:"display_name"`
37+
// TODO: Provisioner
38+
Description types.String `tfsdk:"description"`
39+
ActiveVersionID UUID `tfsdk:"active_version_id"`
40+
ActiveUserCount types.Int64 `tfsdk:"active_user_count"`
41+
Deprecated types.Bool `tfsdk:"deprecated"`
42+
DeprecationMessage types.String `tfsdk:"deprecation_message"`
43+
Icon types.String `tfsdk:"icon"`
44+
45+
DefaultTTLMillis types.Int64 `tfsdk:"default_ttl_ms"`
46+
ActivityBumpMillis types.Int64 `tfsdk:"activity_bump_ms"`
47+
// TODO: AutostopRequirement
48+
// TODO: AutostartRequirement
49+
50+
AllowUserAutostart types.Bool `tfsdk:"allow_user_autostart"`
51+
AllowUserAutostop types.Bool `tfsdk:"allow_user_autostop"`
52+
AllowUserCancelWorkspaceJobs types.Bool `tfsdk:"allow_user_cancel_workspace_jobs"`
53+
54+
FailureTTLMillis types.Int64 `tfsdk:"failure_ttl_ms"`
55+
TimeTilDormantMillis types.Int64 `tfsdk:"time_til_dormant_ms"`
56+
TimeTilDormantAutoDeleteMillis types.Int64 `tfsdk:"time_til_dormant_autodelete_ms"`
57+
58+
RequireActiveVersion types.Bool `tfsdk:"require_active_version"`
59+
// TODO: MaxPortShareLevel
60+
61+
CreatedByUserID UUID `tfsdk:"created_by_user_id"`
62+
CreatedAt types.Int64 `tfsdk:"created_at"` // Unix timestamp
63+
UpdatedAt types.Int64 `tfsdk:"updated_at"` // Unix timestamp
64+
65+
// TODO: ACL-related stuff
66+
}
67+
68+
func (d *TemplateDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
69+
resp.TypeName = req.ProviderTypeName + "_template"
70+
}
71+
72+
func (d *TemplateDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
73+
resp.Schema = schema.Schema{
74+
MarkdownDescription: "An existing template on the Coder deployment.",
75+
76+
Attributes: map[string]schema.Attribute{
77+
"organization_id": schema.StringAttribute{
78+
MarkdownDescription: "ID of the organization the template is associated with. This field will be populated if an ID is supplied. Defaults to the provider default organization ID.",
79+
CustomType: UUIDType,
80+
Optional: true,
81+
Computed: true,
82+
},
83+
"id": schema.StringAttribute{
84+
MarkdownDescription: "The ID of the template to retrieve. This field will be populated if a template name is supplied.",
85+
CustomType: UUIDType,
86+
Optional: true,
87+
Computed: true,
88+
Validators: []validator.String{
89+
stringvalidator.AtLeastOneOf(path.Expressions{
90+
path.MatchRoot("name"),
91+
}...),
92+
},
93+
},
94+
"name": schema.StringAttribute{
95+
MarkdownDescription: "The name of the template to retrieve. This field will be populated if an ID is supplied.",
96+
Optional: true,
97+
Computed: true,
98+
},
99+
100+
"display_name": schema.StringAttribute{
101+
MarkdownDescription: "Display name of the template.",
102+
Computed: true,
103+
},
104+
"description": schema.StringAttribute{
105+
MarkdownDescription: "Description of the template.",
106+
Computed: true,
107+
},
108+
"active_version_id": schema.StringAttribute{
109+
MarkdownDescription: "ID of the active version of the template.",
110+
CustomType: UUIDType,
111+
Computed: true,
112+
},
113+
"active_user_count": schema.Int64Attribute{
114+
MarkdownDescription: "Number of active users using the template.",
115+
Computed: true,
116+
},
117+
"deprecated": schema.BoolAttribute{
118+
MarkdownDescription: "Whether the template is deprecated.",
119+
Computed: true,
120+
},
121+
"deprecation_message": schema.StringAttribute{
122+
MarkdownDescription: "Message to display when the template is deprecated.",
123+
Computed: true,
124+
},
125+
"icon": schema.StringAttribute{
126+
MarkdownDescription: "URL of the template's icon.",
127+
Computed: true,
128+
},
129+
"default_ttl_ms": schema.Int64Attribute{
130+
MarkdownDescription: "Default time-to-live for workspaces created from the template.",
131+
Computed: true,
132+
},
133+
"activity_bump_ms": schema.Int64Attribute{
134+
MarkdownDescription: "Duration to bump the deadline of a workspace when it receives activity.",
135+
Computed: true,
136+
},
137+
"allow_user_autostart": schema.BoolAttribute{
138+
MarkdownDescription: "Whether users can autostart workspaces created from the template.",
139+
Computed: true,
140+
},
141+
"allow_user_autostop": schema.BoolAttribute{
142+
MarkdownDescription: "Whether users can customize autostop behavior for workspaces created from the template.",
143+
Computed: true,
144+
},
145+
"allow_user_cancel_workspace_jobs": schema.BoolAttribute{
146+
MarkdownDescription: "Whether users can cancel jobs in workspaces created from the template.",
147+
Computed: true,
148+
},
149+
"failure_ttl_ms": schema.Int64Attribute{
150+
MarkdownDescription: "Automatic cleanup TTL for failed workspace builds.",
151+
Computed: true,
152+
},
153+
"time_til_dormant_ms": schema.Int64Attribute{
154+
MarkdownDescription: "Duration of inactivity before a workspace is considered dormant.",
155+
Computed: true,
156+
},
157+
"time_til_dormant_autodelete_ms": schema.Int64Attribute{
158+
MarkdownDescription: "Duration of inactivity after the workspace becomes dormant before a workspace is automatically deleted.",
159+
Computed: true,
160+
},
161+
"require_active_version": schema.BoolAttribute{
162+
MarkdownDescription: "Whether workspaces created from the template must be up-to-date on the latest active version.",
163+
Computed: true,
164+
},
165+
"created_by_user_id": schema.StringAttribute{
166+
MarkdownDescription: "ID of the user who created the template.",
167+
CustomType: UUIDType,
168+
Computed: true,
169+
},
170+
"created_at": schema.Int64Attribute{
171+
MarkdownDescription: "Unix timestamp of when the template was created.",
172+
Computed: true,
173+
},
174+
"updated_at": schema.Int64Attribute{
175+
MarkdownDescription: "Unix timestamp of when the template was last updated.",
176+
Computed: true,
177+
},
178+
},
179+
}
180+
}
181+
182+
func (d *TemplateDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
183+
// Prevent panic if the provider has not been configured.
184+
if req.ProviderData == nil {
185+
return
186+
}
187+
188+
data, ok := req.ProviderData.(*CoderdProviderData)
189+
190+
if !ok {
191+
resp.Diagnostics.AddError(
192+
"Unexpected Data Source Configure Type",
193+
fmt.Sprintf("Expected *CoderdProviderData, got: %T. Please report this issue to the provider developers.", req.ProviderData),
194+
)
195+
196+
return
197+
}
198+
199+
d.data = data
200+
}
201+
202+
func (d *TemplateDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
203+
var data TemplateDataSourceModel
204+
205+
// Read Terraform configuration data into the model
206+
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
207+
208+
if resp.Diagnostics.HasError() {
209+
return
210+
}
211+
212+
client := d.data.Client
213+
214+
var (
215+
template codersdk.Template
216+
err error
217+
)
218+
if data.ID.ValueUUID() != uuid.Nil {
219+
template, err = client.Template(ctx, data.ID.ValueUUID())
220+
} else {
221+
if data.OrganizationID.ValueUUID() == uuid.Nil {
222+
data.OrganizationID = UUIDValue(d.data.DefaultOrganizationID)
223+
}
224+
if data.OrganizationID.ValueUUID() == uuid.Nil {
225+
resp.Diagnostics.AddError("Client Error", "name requires organization_id to be set")
226+
return
227+
}
228+
template, err = client.TemplateByName(ctx, data.OrganizationID.ValueUUID(), data.Name.ValueString())
229+
}
230+
if err != nil {
231+
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to get template, got error: %s", err))
232+
return
233+
}
234+
if !data.ID.IsNull() && template.ID.String() != data.ID.ValueString() {
235+
resp.Diagnostics.AddError("Client Error", "Retrieved Template's ID does not match the provided ID")
236+
return
237+
}
238+
if !data.Name.IsNull() && template.Name != data.Name.ValueString() {
239+
resp.Diagnostics.AddError("Client Error", "Retrieved Template's name does not match the provided name")
240+
return
241+
}
242+
if !data.OrganizationID.IsNull() && template.OrganizationID.String() != data.OrganizationID.ValueString() {
243+
resp.Diagnostics.AddError("Client Error", "Retrieved Template's organization ID does not match the provided organization ID")
244+
return
245+
}
246+
247+
data.OrganizationID = UUIDValue(template.OrganizationID)
248+
data.ID = UUIDValue(template.ID)
249+
data.Name = types.StringValue(template.Name)
250+
data.DisplayName = types.StringValue(template.DisplayName)
251+
data.Description = types.StringValue(template.Description)
252+
data.ActiveVersionID = UUIDValue(template.ActiveVersionID)
253+
data.ActiveUserCount = types.Int64Value(int64(template.ActiveUserCount))
254+
data.Deprecated = types.BoolValue(template.Deprecated)
255+
data.DeprecationMessage = types.StringValue(template.DeprecationMessage)
256+
data.Icon = types.StringValue(template.Icon)
257+
data.DefaultTTLMillis = types.Int64Value(template.DefaultTTLMillis)
258+
data.ActivityBumpMillis = types.Int64Value(template.ActivityBumpMillis)
259+
data.AllowUserAutostart = types.BoolValue(template.AllowUserAutostart)
260+
data.AllowUserAutostop = types.BoolValue(template.AllowUserAutostop)
261+
data.AllowUserCancelWorkspaceJobs = types.BoolValue(template.AllowUserCancelWorkspaceJobs)
262+
data.FailureTTLMillis = types.Int64Value(template.FailureTTLMillis)
263+
data.TimeTilDormantMillis = types.Int64Value(template.TimeTilDormantMillis)
264+
data.TimeTilDormantAutoDeleteMillis = types.Int64Value(template.TimeTilDormantAutoDeleteMillis)
265+
data.RequireActiveVersion = types.BoolValue(template.RequireActiveVersion)
266+
data.CreatedByUserID = UUIDValue(template.CreatedByID)
267+
data.CreatedAt = types.Int64Value(template.CreatedAt.Unix())
268+
data.UpdatedAt = types.Int64Value(template.UpdatedAt.Unix())
269+
270+
// Save data into Terraform state
271+
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
272+
}

0 commit comments

Comments
 (0)