Skip to content

Commit c4f2d6c

Browse files
committed
First action
1 parent e99ec05 commit c4f2d6c

File tree

9 files changed

+558
-21
lines changed

9 files changed

+558
-21
lines changed

internal/framework/action_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ import (
1313
func TestActionWithConfigureCompilation(t *testing.T) {
1414
// This test ensures our new types compile correctly
1515
var action ActionWithConfigure
16-
16+
1717
// Test that it has the Meta method from withMeta
1818
if action.Meta() != nil {
1919
t.Error("Expected nil meta before configuration")
2020
}
21-
21+
2222
// Test that it embeds withMeta correctly
2323
action.meta = &conns.AWSClient{}
2424
if action.Meta() == nil {
@@ -32,15 +32,15 @@ func TestActionWithModelCompilation(t *testing.T) {
3232
type testModel struct {
3333
Name string `tfsdk:"name"`
3434
}
35-
35+
3636
// This test ensures our new generic type compiles correctly
3737
var action ActionWithModel[testModel]
38-
38+
3939
// Test that it has the Meta method from ActionWithConfigure
4040
if action.Meta() != nil {
4141
t.Error("Expected nil meta before configuration")
4242
}
43-
43+
4444
// Test that it embeds ActionWithConfigure correctly
4545
action.meta = &conns.AWSClient{}
4646
if action.Meta() == nil {

internal/framework/action_with_model.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package framework
55

66
import (
77
"context"
8+
"fmt"
89

910
"github.com/hashicorp/terraform-plugin-framework/action/schema"
1011
"github.com/hashicorp/terraform-plugin-framework/diag"
@@ -20,6 +21,8 @@ type ActionWithModel[T any] struct {
2021

2122
// ValidateModel validates the action's model against a schema.
2223
func (a *ActionWithModel[T]) ValidateModel(ctx context.Context, schema *schema.UnlinkedSchema) diag.Diagnostics {
24+
fmt.Printf("DEBUG: ActionWithModel.ValidateModel() called with schema having %d attributes\n", len(schema.Attributes))
25+
2326
var diags diag.Diagnostics
2427
state := tfsdk.State{
2528
Raw: tftypes.NewValue(schema.Type().TerraformType(ctx), nil),
@@ -28,6 +31,13 @@ func (a *ActionWithModel[T]) ValidateModel(ctx context.Context, schema *schema.U
2831

2932
diags.Append(a.validateModel(ctx, &state)...)
3033

34+
fmt.Printf("DEBUG: ActionWithModel.ValidateModel() completed, has errors: %t\n", diags.HasError())
35+
if diags.HasError() {
36+
for _, d := range diags {
37+
fmt.Printf("DEBUG: ActionWithModel.ValidateModel() error: %s - %s\n", d.Summary(), d.Detail())
38+
}
39+
}
40+
3141
return diags
3242
}
3343

internal/provider/framework/action_test.go

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -65,16 +65,16 @@ func (t *testAction) ValidateModel(ctx context.Context, schema *schema.UnlinkedS
6565

6666
// Ensure testAction implements required interfaces
6767
var (
68-
_ action.Action = (*testAction)(nil)
69-
_ framework.ActionValidateModel = (*testAction)(nil)
68+
_ action.Action = (*testAction)(nil)
69+
_ framework.ActionValidateModel = (*testAction)(nil)
7070
)
7171

7272
func TestWrappedAction_Basic(t *testing.T) {
7373
ctx := context.Background()
74-
74+
7575
// Create test action
7676
inner := &testAction{}
77-
77+
7878
// Create wrapped action with minimal options
7979
opts := wrappedActionOptions{
8080
bootstrapContext: func(ctx context.Context, getAttribute getAttributeFunc, c *conns.AWSClient) (context.Context, diag.Diagnostics) {
@@ -83,29 +83,29 @@ func TestWrappedAction_Basic(t *testing.T) {
8383
interceptors: interceptorInvocations{},
8484
typeName: "aws_test_action",
8585
}
86-
86+
8787
wrapped := newWrappedAction(inner, opts)
88-
88+
8989
// Test Metadata
9090
metaReq := action.MetadataRequest{
9191
ProviderTypeName: "aws",
9292
}
9393
var metaResp action.MetadataResponse
9494
wrapped.Metadata(ctx, metaReq, &metaResp)
95-
95+
9696
if metaResp.TypeName != "aws_test_action" {
9797
t.Errorf("Expected TypeName 'aws_test_action', got '%s'", metaResp.TypeName)
9898
}
99-
99+
100100
// Test Schema
101101
schemaReq := action.SchemaRequest{}
102102
var schemaResp action.SchemaResponse
103103
wrapped.Schema(ctx, schemaReq, &schemaResp)
104-
104+
105105
if schemaResp.Diagnostics.HasError() {
106106
t.Errorf("Schema method returned errors: %v", schemaResp.Diagnostics)
107107
}
108-
108+
109109
if unlinkedSchema, ok := schemaResp.Schema.(schema.UnlinkedSchema); ok {
110110
if _, exists := unlinkedSchema.Attributes["test_param"]; !exists {
111111
t.Error("Expected 'test_param' attribute in schema")
@@ -117,10 +117,10 @@ func TestWrappedAction_Basic(t *testing.T) {
117117

118118
func TestActionInterceptors_RegionInjection(t *testing.T) {
119119
ctx := context.Background()
120-
120+
121121
// Create test action
122122
inner := &testAction{}
123-
123+
124124
// Create wrapped action with region interceptor
125125
opts := wrappedActionOptions{
126126
bootstrapContext: func(ctx context.Context, getAttribute getAttributeFunc, c *conns.AWSClient) (context.Context, diag.Diagnostics) {
@@ -131,18 +131,18 @@ func TestActionInterceptors_RegionInjection(t *testing.T) {
131131
},
132132
typeName: "aws_test_action",
133133
}
134-
134+
135135
wrapped := newWrappedAction(inner, opts)
136-
136+
137137
// Test Schema with region injection
138138
schemaReq := action.SchemaRequest{}
139139
var schemaResp action.SchemaResponse
140140
wrapped.Schema(ctx, schemaReq, &schemaResp)
141-
141+
142142
if schemaResp.Diagnostics.HasError() {
143143
t.Errorf("Schema method returned errors: %v", schemaResp.Diagnostics)
144144
}
145-
145+
146146
if unlinkedSchema, ok := schemaResp.Schema.(schema.UnlinkedSchema); ok {
147147
if _, exists := unlinkedSchema.Attributes["region"]; !exists {
148148
t.Error("Expected 'region' attribute to be injected into schema")

internal/provider/framework/provider.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,14 @@ func (p *frameworkProvider) EphemeralResources(ctx context.Context) []func() eph
387387
//
388388
// All actions must have unique type names.
389389
func (p *frameworkProvider) Actions(ctx context.Context) []func() action.Action {
390+
fmt.Printf("DEBUG: frameworkProvider.Actions() called, returning %d actions\n", len(p.actions))
391+
for i, actionFunc := range p.actions {
392+
// Create a temporary instance to get the type name
393+
tempAction := actionFunc()
394+
if wrappedAction, ok := tempAction.(*wrappedAction); ok {
395+
fmt.Printf("DEBUG: Action %d: %s\n", i, wrappedAction.opts.typeName)
396+
}
397+
}
390398
return slices.Clone(p.actions)
391399
}
392400

@@ -545,6 +553,8 @@ func (p *frameworkProvider) initialize(ctx context.Context) error {
545553
continue
546554
}
547555

556+
fmt.Printf("DEBUG: Registering action: %s from service package: %s\n", typeName, sp.ServicePackageName())
557+
548558
var isRegionOverrideEnabled bool
549559
if v := v.Region; !tfunique.IsHandleNil(v) && v.Value().IsOverrideEnabled {
550560
isRegionOverrideEnabled = true

internal/provider/framework/region.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package framework
55

66
import (
77
"context"
8+
"fmt"
89

910
"github.com/YakDriver/regexache"
1011
"github.com/hashicorp/terraform-plugin-framework/action"
@@ -417,8 +418,11 @@ func (a actionInjectRegionAttributeInterceptor) schema(ctx context.Context, opts
417418

418419
switch response, when := opts.response, opts.when; when {
419420
case After:
421+
fmt.Printf("DEBUG: actionInjectRegionAttributeInterceptor.schema() called AFTER, schema type: %T\n", response.Schema)
420422
if schema, ok := response.Schema.(aschema.UnlinkedSchema); ok {
423+
fmt.Printf("DEBUG: actionInjectRegionAttributeInterceptor.schema() processing UnlinkedSchema with %d attributes\n", len(schema.Attributes))
421424
if _, exists := schema.Attributes[names.AttrRegion]; !exists {
425+
fmt.Printf("DEBUG: actionInjectRegionAttributeInterceptor.schema() injecting region attribute\n")
422426
// Inject a top-level "region" attribute.
423427
if schema.Attributes == nil {
424428
schema.Attributes = make(map[string]aschema.Attribute)
@@ -428,8 +432,15 @@ func (a actionInjectRegionAttributeInterceptor) schema(ctx context.Context, opts
428432
Description: names.TopLevelRegionAttributeDescription,
429433
}
430434
response.Schema = schema
435+
fmt.Printf("DEBUG: actionInjectRegionAttributeInterceptor.schema() region attribute injected, now %d attributes\n", len(schema.Attributes))
436+
} else {
437+
fmt.Printf("DEBUG: actionInjectRegionAttributeInterceptor.schema() region attribute already exists\n")
431438
}
439+
} else {
440+
fmt.Printf("DEBUG: actionInjectRegionAttributeInterceptor.schema() schema is NOT UnlinkedSchema, got %T\n", response.Schema)
432441
}
442+
default:
443+
fmt.Printf("DEBUG: actionInjectRegionAttributeInterceptor.schema() called with when=%v\n", when)
433444
}
434445

435446
return diags

internal/provider/framework/wrap.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package framework
55

66
import (
77
"context"
8+
"fmt"
89

910
"github.com/hashicorp/terraform-plugin-framework/action"
1011
aschema "github.com/hashicorp/terraform-plugin-framework/action/schema"
@@ -304,13 +305,17 @@ func newWrappedAction(inner action.Action, opts wrappedActionOptions) action.Act
304305

305306
func (w *wrappedAction) Metadata(ctx context.Context, request action.MetadataRequest, response *action.MetadataResponse) {
306307
// This method does not call down to the inner action.
308+
fmt.Printf("DEBUG: wrappedAction.Metadata() called, setting TypeName to: %s\n", w.opts.typeName)
307309
response.TypeName = w.opts.typeName
308310
}
309311

310312
func (w *wrappedAction) Schema(ctx context.Context, request action.SchemaRequest, response *action.SchemaResponse) {
313+
fmt.Printf("DEBUG: wrappedAction.Schema() called for action: %s\n", w.opts.typeName)
314+
311315
ctx, diags := w.opts.bootstrapContext(ctx, nil, w.meta)
312316
response.Diagnostics.Append(diags...)
313317
if response.Diagnostics.HasError() {
318+
fmt.Printf("DEBUG: wrappedAction.Schema() bootstrap context failed for %s\n", w.opts.typeName)
314319
return
315320
}
316321

@@ -320,20 +325,42 @@ func (w *wrappedAction) Schema(ctx context.Context, request action.SchemaRequest
320325
}
321326
response.Diagnostics.Append(interceptedHandler(w.opts.interceptors.actionSchema(), f, w.meta)(ctx, &request, response)...)
322327

328+
fmt.Printf("DEBUG: wrappedAction.Schema() after interceptors, schema type: %T\n", response.Schema)
329+
323330
// Validate the action's model against the schema.
324331
if v, ok := w.inner.(framework.ActionValidateModel); ok {
332+
fmt.Printf("DEBUG: wrappedAction.Schema() action implements ActionValidateModel for %s\n", w.opts.typeName)
325333
if schema, ok := response.Schema.(aschema.UnlinkedSchema); ok {
334+
fmt.Printf("DEBUG: wrappedAction.Schema() schema is UnlinkedSchema with %d attributes for %s\n", len(schema.Attributes), w.opts.typeName)
326335
response.Diagnostics.Append(v.ValidateModel(ctx, &schema)...)
327336
if response.Diagnostics.HasError() {
337+
fmt.Printf("DEBUG: wrappedAction.Schema() model validation failed for %s\n", w.opts.typeName)
328338
response.Diagnostics.AddError("action model validation error", w.opts.typeName)
329339
return
330340
}
341+
fmt.Printf("DEBUG: wrappedAction.Schema() model validation succeeded for %s\n", w.opts.typeName)
331342
} else {
343+
fmt.Printf("DEBUG: wrappedAction.Schema() schema is NOT UnlinkedSchema, got %T for %s\n", response.Schema, w.opts.typeName)
332344
response.Diagnostics.AddError("unsupported action schema type", w.opts.typeName)
333345
}
334346
} else {
347+
fmt.Printf("DEBUG: wrappedAction.Schema() action does NOT implement ActionValidateModel for %s\n", w.opts.typeName)
335348
response.Diagnostics.AddError("missing framework.ActionValidateModel", w.opts.typeName)
336349
}
350+
351+
fmt.Printf("DEBUG: wrappedAction.Schema() completed for %s, has errors: %t\n", w.opts.typeName, response.Diagnostics.HasError())
352+
353+
// Final debug: show what we're actually returning
354+
if !response.Diagnostics.HasError() {
355+
if schema, ok := response.Schema.(aschema.UnlinkedSchema); ok {
356+
fmt.Printf("DEBUG: wrappedAction.Schema() FINAL SCHEMA for %s:\n", w.opts.typeName)
357+
fmt.Printf("DEBUG: Description: %s\n", schema.Description)
358+
fmt.Printf("DEBUG: Attributes (%d):\n", len(schema.Attributes))
359+
for name, attr := range schema.Attributes {
360+
fmt.Printf("DEBUG: - %s: %T\n", name, attr)
361+
}
362+
}
363+
}
337364
}
338365

339366
func (w *wrappedAction) Invoke(ctx context.Context, request action.InvokeRequest, response *action.InvokeResponse) {

internal/service/ec2/service_package_gen.go

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)