Skip to content

Commit cc758b8

Browse files
authored
[Internal] Generate both SdkV2-compatible and Plugin Framework-compatible structures (#4332)
## Changes To make it possible to implement new resources following the Plugin Framework's recommendation to use attributes while allowing resources to be migrated from SDKv2 to the Plugin Framework without breaking, we will create two copies of each code-generated structure in the Terraform provider. The structures with no suffix should be used for new resources. The structures with the `_SdkV2` suffix should be used for resources in the plugin framework that are migrated from SDKv2. ## Tests <!-- How is this tested? Please see the checklist below and also describe any other relevant tests --> - [ ] `make test` run locally - [ ] relevant change in `docs/` folder - [ ] covered with integration tests in `internal/acceptance` - [ ] using Go SDK - [ ] using TF Plugin Framework
1 parent d2c6a4f commit cc758b8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+148080
-6893
lines changed

.gitattributes

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,40 @@
1+
internal/service/apps_tf/legacy_model.go linguist-generated=true
12
internal/service/apps_tf/model.go linguist-generated=true
3+
internal/service/billing_tf/legacy_model.go linguist-generated=true
24
internal/service/billing_tf/model.go linguist-generated=true
5+
internal/service/catalog_tf/legacy_model.go linguist-generated=true
36
internal/service/catalog_tf/model.go linguist-generated=true
7+
internal/service/cleanrooms_tf/legacy_model.go linguist-generated=true
48
internal/service/cleanrooms_tf/model.go linguist-generated=true
9+
internal/service/compute_tf/legacy_model.go linguist-generated=true
510
internal/service/compute_tf/model.go linguist-generated=true
11+
internal/service/dashboards_tf/legacy_model.go linguist-generated=true
612
internal/service/dashboards_tf/model.go linguist-generated=true
13+
internal/service/files_tf/legacy_model.go linguist-generated=true
714
internal/service/files_tf/model.go linguist-generated=true
15+
internal/service/iam_tf/legacy_model.go linguist-generated=true
816
internal/service/iam_tf/model.go linguist-generated=true
17+
internal/service/jobs_tf/legacy_model.go linguist-generated=true
918
internal/service/jobs_tf/model.go linguist-generated=true
19+
internal/service/marketplace_tf/legacy_model.go linguist-generated=true
1020
internal/service/marketplace_tf/model.go linguist-generated=true
21+
internal/service/ml_tf/legacy_model.go linguist-generated=true
1122
internal/service/ml_tf/model.go linguist-generated=true
23+
internal/service/oauth2_tf/legacy_model.go linguist-generated=true
1224
internal/service/oauth2_tf/model.go linguist-generated=true
25+
internal/service/pipelines_tf/legacy_model.go linguist-generated=true
1326
internal/service/pipelines_tf/model.go linguist-generated=true
27+
internal/service/provisioning_tf/legacy_model.go linguist-generated=true
1428
internal/service/provisioning_tf/model.go linguist-generated=true
29+
internal/service/serving_tf/legacy_model.go linguist-generated=true
1530
internal/service/serving_tf/model.go linguist-generated=true
31+
internal/service/settings_tf/legacy_model.go linguist-generated=true
1632
internal/service/settings_tf/model.go linguist-generated=true
33+
internal/service/sharing_tf/legacy_model.go linguist-generated=true
1734
internal/service/sharing_tf/model.go linguist-generated=true
35+
internal/service/sql_tf/legacy_model.go linguist-generated=true
1836
internal/service/sql_tf/model.go linguist-generated=true
37+
internal/service/vectorsearch_tf/legacy_model.go linguist-generated=true
1938
internal/service/vectorsearch_tf/model.go linguist-generated=true
39+
internal/service/workspace_tf/legacy_model.go linguist-generated=true
2040
internal/service/workspace_tf/model.go linguist-generated=true

CONTRIBUTING.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,10 @@ We are migrating the resource from SDKv2 to Plugin Framework provider and hence
120120

121121
### Adding a new resource
122122
1. Check if the directory for this particular resource exists under `internal/providers/pluginfw/products`, if not create the directory eg: `cluster`, `volume` etc... Please note: Resources and Data sources are organized under the same package for that service.
123-
2. Create a file with resource_resource-name.go and write the CRUD methods, schema for that resource. For reference, please take a look at existing resources eg: `resource_quality_monitor.go`. Make sure to set the user agent in all the CRUD methods. In the `Metadata()`, if the resource is to be used as default, use the method `GetDatabricksProductionName()` else use `GetDatabricksStagingName()` which suffixes the name with `_pluginframework`.
123+
2. Create a file with resource_resource-name.go and write the CRUD methods, schema for that resource. For reference, please take a look at existing resources eg: `resource_app.go`.
124+
- Make sure to set the user agent in all the CRUD methods.
125+
- In the `Metadata()`, use the method `GetDatabricksProductionName()`.
126+
- In the `Schema()` method, import the appropriate struct from the `internal/service/{package}_tf` package and use the `ResourceStructToSchema` method to convert the struct to schema. Use the struct that does not have the `_SdkV2` suffix.
124127
3. Create a file with `resource_resource-name_acc_test.go` and add integration tests here.
125128
4. Create a file with `resource_resource-name_test.go` and add unit tests here. Note: Please make sure to abstract specific method of the resource so they are unit test friendly and not testing internal part of terraform plugin framework library. You can compare the diagnostics, for example: please take a look at: `data_cluster_test.go`
126129
5. Add the resource under `internal/providers/pluginfw/pluginfw.go` in `Resources()` method. Please update the list so that it stays in alphabetically sorted order.
@@ -139,9 +142,9 @@ There must not be any behaviour change or schema change when migrating a resourc
139142
- Please make sure there are no breaking differences due to changes in schema by running: `make diff-schema`.
140143
- Integration tests shouldn't require any major changes.
141144
142-
By default, `ResourceStructToSchema` will convert a `types.List` field to a `ListAttribute` or `ListNestedAttribute`. For resources or data sources migrated from the SDKv2, `ListNestedBlock` must be used for such fields. To do this, call `cs.ConfigureAsSdkV2Compatible()` in the `ResourceStructToSchema` callback:
145+
By default, `ResourceStructToSchema` will convert a `types.List` field to a `ListAttribute` or `ListNestedAttribute`. For resources or data sources migrated from the SDKv2, `ListNestedBlock` must be used for such fields. To do this, use the `_SdkV2` variant from the `internal/service/{package}_tf` package when defining the resource schema and when interacting with the plan, config and state. Additionally, in the `Schema()` method, call `cs.ConfigureAsSdkV2Compatible()` in the `ResourceStructToSchema` callback:
143146
```go
144-
resp.Schema = tfschema.ResourceStructToSchema(ctx, Resource{}, func(c tfschema.CustomizableSchema) tfschema.CustomizableSchema {
147+
resp.Schema = tfschema.ResourceStructToSchema(ctx, Resource_SdkV2{}, func(c tfschema.CustomizableSchema) tfschema.CustomizableSchema {
145148
cs.ConfigureAsSdkV2Compatible()
146149
// Add any additional configuration here
147150
return cs

internal/providers/pluginfw/products/catalog/data_functions.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ type FunctionsData struct {
4040

4141
func (FunctionsData) GetComplexFieldTypes(context.Context) map[string]reflect.Type {
4242
return map[string]reflect.Type{
43-
"functions": reflect.TypeOf(catalog_tf.FunctionInfo{}),
43+
"functions": reflect.TypeOf(catalog_tf.FunctionInfo_SdkV2{}),
4444
}
4545
}
4646

internal/providers/pluginfw/products/cluster/data_cluster.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ type ClusterInfo struct {
4141

4242
func (ClusterInfo) GetComplexFieldTypes(context.Context) map[string]reflect.Type {
4343
return map[string]reflect.Type{
44-
"cluster_info": reflect.TypeOf(compute_tf.ClusterDetails{}),
44+
"cluster_info": reflect.TypeOf(compute_tf.ClusterDetails_SdkV2{}),
4545
}
4646
}
4747

@@ -85,7 +85,7 @@ func (d *ClusterDataSource) Read(ctx context.Context, req datasource.ReadRequest
8585
return
8686
}
8787

88-
var tfCluster compute_tf.ClusterDetails
88+
var tfCluster compute_tf.ClusterDetails_SdkV2
8989
resp.Diagnostics.Append(converters.GoSdkToTfSdkStruct(ctx, cluster, &tfCluster)...)
9090
if resp.Diagnostics.HasError() {
9191
return

internal/providers/pluginfw/products/library/resource_library.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ func readLibrary(ctx context.Context, w *databricks.WorkspaceClient, waitParams
7373
}
7474

7575
type LibraryExtended struct {
76-
compute_tf.Library
76+
compute_tf.Library_SdkV2
7777
ClusterId types.String `tfsdk:"cluster_id"`
7878
ID types.String `tfsdk:"id" tf:"optional,computed"` // Adding ID field to stay compatible with SDKv2
7979
}

internal/providers/pluginfw/products/qualitymonitor/resource_quality_monitor.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ func waitForMonitor(ctx context.Context, w *databricks.WorkspaceClient, monitor
5656
}
5757

5858
type MonitorInfoExtended struct {
59-
catalog_tf.MonitorInfo
59+
catalog_tf.MonitorInfo_SdkV2
6060
WarehouseId types.String `tfsdk:"warehouse_id" tf:"optional"`
6161
SkipBuiltinDashboard types.Bool `tfsdk:"skip_builtin_dashboard" tf:"optional"`
6262
ID types.String `tfsdk:"id" tf:"optional,computed"` // Adding ID field to stay compatible with SDKv2
@@ -65,7 +65,7 @@ type MonitorInfoExtended struct {
6565
var _ pluginfwcommon.ComplexFieldTypeProvider = MonitorInfoExtended{}
6666

6767
func (m MonitorInfoExtended) GetComplexFieldTypes(ctx context.Context) map[string]reflect.Type {
68-
return m.MonitorInfo.GetComplexFieldTypes(ctx)
68+
return m.MonitorInfo_SdkV2.GetComplexFieldTypes(ctx)
6969
}
7070

7171
type QualityMonitorResource struct {

internal/providers/pluginfw/products/registered_model/data_registered_model.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ type RegisteredModelData struct {
4242

4343
func (RegisteredModelData) GetComplexFieldTypes(context.Context) map[string]reflect.Type {
4444
return map[string]reflect.Type{
45-
"model_info": reflect.TypeOf(catalog_tf.RegisteredModelInfo{}),
45+
"model_info": reflect.TypeOf(catalog_tf.RegisteredModelInfo_SdkV2{}),
4646
}
4747
}
4848

internal/providers/pluginfw/products/registered_model/data_registered_model_versions.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ type RegisteredModelVersionsData struct {
3333

3434
func (RegisteredModelVersionsData) GetComplexFieldTypes(context.Context) map[string]reflect.Type {
3535
return map[string]reflect.Type{
36-
"model_versions": reflect.TypeOf(catalog_tf.ModelVersionInfo{}),
36+
"model_versions": reflect.TypeOf(catalog_tf.ModelVersionInfo_SdkV2{}),
3737
}
3838
}
3939

@@ -76,13 +76,13 @@ func (d *RegisteredModelVersionsDataSource) Read(ctx context.Context, req dataso
7676
}
7777
var tfModelVersions []attr.Value
7878
for _, modelVersionSdk := range modelVersions.ModelVersions {
79-
var modelVersion catalog_tf.ModelVersionInfo
79+
var modelVersion catalog_tf.ModelVersionInfo_SdkV2
8080
resp.Diagnostics.Append(converters.GoSdkToTfSdkStruct(ctx, modelVersionSdk, &modelVersion)...)
8181
if resp.Diagnostics.HasError() {
8282
return
8383
}
8484
tfModelVersions = append(tfModelVersions, modelVersion.ToObjectValue(ctx))
8585
}
86-
registeredModelVersions.ModelVersions = types.ListValueMust(catalog_tf.ModelVersionInfo{}.Type(ctx), tfModelVersions)
86+
registeredModelVersions.ModelVersions = types.ListValueMust(catalog_tf.ModelVersionInfo_SdkV2{}.Type(ctx), tfModelVersions)
8787
resp.Diagnostics.Append(resp.State.Set(ctx, registeredModelVersions)...)
8888
}

internal/providers/pluginfw/products/serving/data_serving_endpoints.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ type ServingEndpointsData struct {
3232

3333
func (ServingEndpointsData) GetComplexFieldTypes(context.Context) map[string]reflect.Type {
3434
return map[string]reflect.Type{
35-
"endpoints": reflect.TypeOf(serving_tf.ServingEndpoint{}),
35+
"endpoints": reflect.TypeOf(serving_tf.ServingEndpoint_SdkV2{}),
3636
}
3737
}
3838

@@ -77,13 +77,13 @@ func (d *ServingEndpointsDataSource) Read(ctx context.Context, req datasource.Re
7777
}
7878
tfEndpoints := []attr.Value{}
7979
for _, endpoint := range endpointsInfoSdk {
80-
var endpointsInfo serving_tf.ServingEndpoint
80+
var endpointsInfo serving_tf.ServingEndpoint_SdkV2
8181
resp.Diagnostics.Append(converters.GoSdkToTfSdkStruct(ctx, endpoint, &endpointsInfo)...)
8282
if resp.Diagnostics.HasError() {
8383
return
8484
}
8585
tfEndpoints = append(tfEndpoints, endpointsInfo.ToObjectValue(ctx))
8686
}
87-
endpoints.Endpoints = types.ListValueMust(serving_tf.ServingEndpoint{}.Type(ctx), tfEndpoints)
87+
endpoints.Endpoints = types.ListValueMust(serving_tf.ServingEndpoint_SdkV2{}.Type(ctx), tfEndpoints)
8888
resp.Diagnostics.Append(resp.State.Set(ctx, endpoints)...)
8989
}

internal/providers/pluginfw/products/sharing/resource_share.go

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,13 @@ func ResourceShare() resource.Resource {
3030
}
3131

3232
type ShareInfoExtended struct {
33-
sharing_tf.ShareInfo
33+
sharing_tf.ShareInfo_SdkV2
3434
}
3535

3636
var _ pluginfwcommon.ComplexFieldTypeProvider = ShareInfoExtended{}
3737

3838
func (s ShareInfoExtended) GetComplexFieldTypes(ctx context.Context) map[string]reflect.Type {
39-
return s.ShareInfo.GetComplexFieldTypes(ctx)
39+
return s.ShareInfo_SdkV2.GetComplexFieldTypes(ctx)
4040
}
4141

4242
func matchOrder[T any, K comparable](target, reference []T, keyFunc func(T) K) {
@@ -155,6 +155,8 @@ func (r *ShareResource) Schema(ctx context.Context, req resource.SchemaRequest,
155155
c.SetRequired("object", "data_object_type")
156156
c.SetRequired("object", "partition", "value", "op")
157157
c.SetRequired("object", "partition", "value", "name")
158+
159+
c.SetOptional("owner")
158160
return c
159161
})
160162
resp.Schema = schema.Schema{
@@ -408,36 +410,36 @@ func (r *ShareResource) Delete(ctx context.Context, req resource.DeleteRequest,
408410
}
409411

410412
type effectiveFieldsAction interface {
411-
resourceLevel(*ShareInfoExtended, sharing_tf.ShareInfo)
412-
objectLevel(*sharing_tf.SharedDataObject, sharing_tf.SharedDataObject)
413+
resourceLevel(*ShareInfoExtended, sharing_tf.ShareInfo_SdkV2)
414+
objectLevel(*sharing_tf.SharedDataObject_SdkV2, sharing_tf.SharedDataObject_SdkV2)
413415
}
414416

415417
type effectiveFieldsActionCreateOrUpdate struct{}
416418

417-
func (effectiveFieldsActionCreateOrUpdate) resourceLevel(state *ShareInfoExtended, plan sharing_tf.ShareInfo) {
419+
func (effectiveFieldsActionCreateOrUpdate) resourceLevel(state *ShareInfoExtended, plan sharing_tf.ShareInfo_SdkV2) {
418420
state.SyncEffectiveFieldsDuringCreateOrUpdate(plan)
419421
}
420422

421-
func (effectiveFieldsActionCreateOrUpdate) objectLevel(state *sharing_tf.SharedDataObject, plan sharing_tf.SharedDataObject) {
423+
func (effectiveFieldsActionCreateOrUpdate) objectLevel(state *sharing_tf.SharedDataObject_SdkV2, plan sharing_tf.SharedDataObject_SdkV2) {
422424
state.SyncEffectiveFieldsDuringCreateOrUpdate(plan)
423425
}
424426

425427
type effectiveFieldsActionRead struct{}
426428

427-
func (effectiveFieldsActionRead) resourceLevel(state *ShareInfoExtended, plan sharing_tf.ShareInfo) {
429+
func (effectiveFieldsActionRead) resourceLevel(state *ShareInfoExtended, plan sharing_tf.ShareInfo_SdkV2) {
428430
state.SyncEffectiveFieldsDuringRead(plan)
429431
}
430432

431-
func (effectiveFieldsActionRead) objectLevel(state *sharing_tf.SharedDataObject, plan sharing_tf.SharedDataObject) {
433+
func (effectiveFieldsActionRead) objectLevel(state *sharing_tf.SharedDataObject_SdkV2, plan sharing_tf.SharedDataObject_SdkV2) {
432434
state.SyncEffectiveFieldsDuringRead(plan)
433435
}
434436

435437
func (r *ShareResource) syncEffectiveFields(ctx context.Context, plan, state ShareInfoExtended, mode effectiveFieldsAction) (ShareInfoExtended, diag.Diagnostics) {
436438
var d diag.Diagnostics
437-
mode.resourceLevel(&state, plan.ShareInfo)
439+
mode.resourceLevel(&state, plan.ShareInfo_SdkV2)
438440
planObjects, _ := plan.GetObjects(ctx)
439441
stateObjects, _ := state.GetObjects(ctx)
440-
finalObjects := []sharing_tf.SharedDataObject{}
442+
finalObjects := []sharing_tf.SharedDataObject_SdkV2{}
441443
for i := range stateObjects {
442444
mode.objectLevel(&stateObjects[i], planObjects[i])
443445
finalObjects = append(finalObjects, stateObjects[i])

0 commit comments

Comments
 (0)