Skip to content

Commit 0f9ca3b

Browse files
committed
Keep extension data source state durable
1 parent a06c10b commit 0f9ca3b

3 files changed

Lines changed: 21 additions & 65 deletions

File tree

docs/data-sources/extension.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,4 @@ Lookup durable Kernel extension metadata.
2424
### Read-Only
2525

2626
- `created_at` (String) Extension creation timestamp.
27-
- `last_used_at` (String) Timestamp the extension was last used, if ever.
2827
- `size_bytes` (Number) Extension archive size in bytes.

internal/datasources/extension/datasource.go

Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,11 @@ type extensionDataSource struct {
3131
}
3232

3333
type extensionModel struct {
34-
ID types.String `tfsdk:"id"`
35-
Name types.String `tfsdk:"name"`
36-
ProjectID types.String `tfsdk:"project_id"`
37-
CreatedAt types.String `tfsdk:"created_at"`
38-
SizeBytes types.Int64 `tfsdk:"size_bytes"`
39-
LastUsedAt types.String `tfsdk:"last_used_at"`
34+
ID types.String `tfsdk:"id"`
35+
Name types.String `tfsdk:"name"`
36+
ProjectID types.String `tfsdk:"project_id"`
37+
CreatedAt types.String `tfsdk:"created_at"`
38+
SizeBytes types.Int64 `tfsdk:"size_bytes"`
4039
}
4140

4241
func NewDataSource() datasource.DataSource {
@@ -80,10 +79,6 @@ func (d *extensionDataSource) Schema(ctx context.Context, req datasource.SchemaR
8079
Computed: true,
8180
MarkdownDescription: "Extension archive size in bytes.",
8281
},
83-
"last_used_at": dschema.StringAttribute{
84-
Computed: true,
85-
MarkdownDescription: "Timestamp the extension was last used, if ever.",
86-
},
8782
},
8883
}
8984
}
@@ -209,26 +204,15 @@ func flattenExtension(extension kernel.ExtensionGetResponse) (extensionModel, di
209204
}
210205
}
211206

212-
// last_used_at is nullable (an extension that has never been used); a null
213-
// reads as not-present via FieldPresent, leaving the attribute null.
214-
lastUsedAt := types.StringNull()
215-
if datasources.FieldPresent(extension.JSON.LastUsedAt.Raw()) {
216-
if !datasources.ValidResponseTime(extension.JSON.LastUsedAt.Raw(), extension.JSON.LastUsedAt.Valid(), extension.LastUsedAt) {
217-
datasources.AddInvalidResponseField(&diags, "Extension", "last_used_at")
218-
} else {
219-
lastUsedAt = types.StringValue(extension.LastUsedAt.Format(time.RFC3339Nano))
220-
}
221-
}
222207
if diags.HasError() {
223208
return extensionModel{}, diags
224209
}
225210

226211
return extensionModel{
227-
ID: types.StringValue(extension.ID),
228-
Name: name,
229-
CreatedAt: types.StringValue(extension.CreatedAt.Format(time.RFC3339Nano)),
230-
SizeBytes: types.Int64Value(extension.SizeBytes),
231-
LastUsedAt: lastUsedAt,
212+
ID: types.StringValue(extension.ID),
213+
Name: name,
214+
CreatedAt: types.StringValue(extension.CreatedAt.Format(time.RFC3339Nano)),
215+
SizeBytes: types.Int64Value(extension.SizeBytes),
232216
}, diags
233217
}
234218

internal/datasources/extension/datasource_test.go

Lines changed: 12 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -115,12 +115,12 @@ func TestDataSourceMetadataAndSchema(t *testing.T) {
115115

116116
var schema datasource.SchemaResponse
117117
ds.Schema(context.Background(), datasource.SchemaRequest{}, &schema)
118-
for _, name := range []string{"id", "name", "created_at", "size_bytes", "last_used_at"} {
118+
for _, name := range []string{"id", "name", "created_at", "size_bytes"} {
119119
if _, ok := schema.Schema.Attributes[name]; !ok {
120120
t.Fatalf("schema missing %s attribute", name)
121121
}
122122
}
123-
for _, name := range []string{"download_url", "zip_file"} {
123+
for _, name := range []string{"download_url", "zip_file", "last_used_at"} {
124124
if _, ok := schema.Schema.Attributes[name]; ok {
125125
t.Fatalf("schema should not include %s", name)
126126
}
@@ -168,9 +168,6 @@ func TestReadSetsTerraformState(t *testing.T) {
168168
if state.SizeBytes.ValueInt64() != 1234 {
169169
t.Fatalf("state size_bytes = %d, want 1234", state.SizeBytes.ValueInt64())
170170
}
171-
if state.LastUsedAt.ValueString() != "2026-06-05T12:00:00Z" {
172-
t.Fatalf("state last_used_at = %q, want 2026-06-05T12:00:00Z", state.LastUsedAt.ValueString())
173-
}
174171
}
175172

176173
func TestReadExtensionByID(t *testing.T) {
@@ -237,24 +234,6 @@ func TestReadExtensionAllowsNullableName(t *testing.T) {
237234
}
238235
}
239236

240-
func TestReadExtensionAllowsNullableLastUsedAt(t *testing.T) {
241-
t.Parallel()
242-
243-
ds := newDataSourceWithClient(fakeExtensionClient{
244-
get: func(ctx context.Context, projectID, idOrName string) (*kernel.ExtensionGetResponse, error) {
245-
return extensionWithoutLastUsedForTest("extension-1", "Extension"), nil
246-
},
247-
})
248-
249-
state, diags := ds.read(context.Background(), extensionModel{ID: types.StringValue("extension-1")})
250-
if diags.HasError() {
251-
t.Fatalf("unexpected diagnostics: %v", diags)
252-
}
253-
if !state.LastUsedAt.IsNull() {
254-
t.Fatalf("state last_used_at = %q, want null", state.LastUsedAt.ValueString())
255-
}
256-
}
257-
258237
func TestReadRejectsExtensionNotFound(t *testing.T) {
259238
t.Parallel()
260239

@@ -339,10 +318,6 @@ func extensionWithoutNameForTest(id string) *kernel.ExtensionGetResponse {
339318
return extensionFromJSON(`{"id":"` + id + `","name":null,"created_at":"2026-06-05T12:00:00Z","size_bytes":1234,"last_used_at":"2026-06-05T12:00:00Z"}`)
340319
}
341320

342-
func extensionWithoutLastUsedForTest(id, name string) *kernel.ExtensionGetResponse {
343-
return extensionFromJSON(`{"id":"` + id + `","name":"` + name + `","created_at":"2026-06-05T12:00:00Z","size_bytes":1234,"last_used_at":null}`)
344-
}
345-
346321
func invalidExtension() *kernel.ExtensionGetResponse {
347322
extension := extensionForTest("extension-1", "Extension")
348323
extension.CreatedAt = time.Time{}
@@ -362,21 +337,19 @@ func extensionConfigValue(id, name tftypes.Value) tftypes.Value {
362337
return tftypes.NewValue(
363338
tftypes.Object{
364339
AttributeTypes: map[string]tftypes.Type{
365-
"id": tftypes.String,
366-
"name": tftypes.String,
367-
"project_id": tftypes.String,
368-
"created_at": tftypes.String,
369-
"size_bytes": tftypes.Number,
370-
"last_used_at": tftypes.String,
340+
"id": tftypes.String,
341+
"name": tftypes.String,
342+
"project_id": tftypes.String,
343+
"created_at": tftypes.String,
344+
"size_bytes": tftypes.Number,
371345
},
372346
},
373347
map[string]tftypes.Value{
374-
"id": id,
375-
"name": name,
376-
"project_id": tftypes.NewValue(tftypes.String, nil),
377-
"created_at": tftypes.NewValue(tftypes.String, nil),
378-
"size_bytes": tftypes.NewValue(tftypes.Number, nil),
379-
"last_used_at": tftypes.NewValue(tftypes.String, nil),
348+
"id": id,
349+
"name": name,
350+
"project_id": tftypes.NewValue(tftypes.String, nil),
351+
"created_at": tftypes.NewValue(tftypes.String, nil),
352+
"size_bytes": tftypes.NewValue(tftypes.Number, nil),
380353
},
381354
)
382355
}

0 commit comments

Comments
 (0)