Skip to content

Commit 5b6b519

Browse files
authored
[Exporter] Initial support for resources implemented with plugin framework (#5176)
## Changes <!-- Summary of your changes that are easy to understand --> This PR adds support for Terraform Plugin Framework-based resources to the exporter, which previously only supported legacy SDKv2 resources. The implementation uses a hybrid approach that maximizes code reuse (~70%) while respecting the framework-specific HCL syntax differences. Resolves: #4050 ### Key Changes **Abstraction Layer**: Introduced `ResourceDataWrapper`, `SchemaWrapper`, and `FieldSchema` interfaces in `exporter/abstractions.go` to provide a unified way to interact with both SDKv2's `schema.ResourceData` and Plugin Framework's `tfsdk.State`. These abstractions enable the exporter to read resource data, access schemas, and query field types consistently across both frameworks. **Unified Code Generation**: Implemented a hybrid HCL generation approach in `exporter/codegen.go` with a single entry point `unifiedDataToHcl()`. The implementation extracts ~70% of common logic into shared helper functions (`extractFieldsForGeneration()`, `generateDependsOnAttribute()`), while maintaining framework-specific functions (`generateSdkv2Field()`, `generatePluginFrameworkField()`) for handling the key difference: SDKv2 generates nested structures as blocks (`evaluation { ... }`), while Plugin Framework uses attribute syntax (`evaluation = { ... }`). **New Unified Callbacks**: Added `ShouldOmitFieldUnified` and `ShouldGenerateFieldUnified` to the `importable` struct, which work with both frameworks through the abstraction layers. Legacy callbacks (`ShouldOmitField`, `ShouldGenerateField`) remain for backward compatibility, and resources can be gradually migrated to the unified versions. The default omission logic was also corrected to properly skip all computed fields, matching the original SDKv2 behavior. **Plugin Framework Resource Support**: Implemented full support for `databricks_alert_v2` as the first Plugin Framework resource. The implementation includes proper state initialization, conversion helpers (`convertPluginFrameworkToGoSdk`), dependency emission, and correct handling of nested attributes. Added comprehensive test fixtures (`emptyAlertsV2`) to ensure compatibility with existing test suites. ### Testing & Documentation All existing tests pass, including critical code generation tests (`TestNotebookGeneration`, `TestDirectoryGeneration`, `TestImportingSqlObjects`). Updated `AGENTS.md` with the new unified code generation architecture and added the exporter architecture section. Updated `docs/guides/experimental-exporter.md` support matrix to reflect support for both `databricks_alert` and `databricks_alert_v2` resources. ### Benefits This implementation maintains 100% backward compatibility with existing SDKv2 resources while enabling easy addition of new Plugin Framework resources. The unified approach reduces technical debt, provides a single source of truth for business logic, and makes future maintenance significantly easier as the provider transitions to Plugin Framework. ## Tests <!-- How is this tested? Please see the checklist below and also describe any other relevant tests --> - [x] `make test` run locally - [x] relevant change in `docs/` folder - [ ] covered with integration tests in `internal/acceptance` - [ ] using Go SDK - [x] using TF Plugin Framework - [x] has entry in `NEXT_CHANGELOG.md` file
1 parent 29ebaa9 commit 5b6b519

File tree

12 files changed

+1834
-64
lines changed

12 files changed

+1834
-64
lines changed

AGENTS.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,45 @@ Resources are being migrated from SDKv2 to Plugin Framework. When migrating:
9595
- `TestMwsAcc*` - Account-level tests across all clouds
9696
- `TestUcAcc*` - Unity Catalog tests across all clouds
9797

98+
### Exporter Architecture
99+
100+
The exporter (`exporter/` directory) generates Terraform configuration (`.tf` files) and import scripts from existing Databricks resources.
101+
102+
#### Unified HCL Code Generation
103+
104+
The exporter uses a **unified code generation approach** for both SDKv2 and Plugin Framework resources:
105+
106+
**Entry Point**: `unifiedDataToHcl()` in `exporter/codegen.go`
107+
- Works with both SDKv2 and Plugin Framework resources through abstraction layers
108+
- Uses `ResourceDataWrapper` and `SchemaWrapper` interfaces for unified data access
109+
- Extracts ~70% of common logic into shared helper functions
110+
111+
**Architecture**:
112+
```
113+
unifiedDataToHcl()
114+
├── extractFieldsForGeneration() ← Shared: field iteration, omission, variable refs, skip logic
115+
├── generateSdkv2Field() ← SDKv2-specific: generates blocks
116+
├── generatePluginFrameworkField() ← Plugin Framework-specific: generates attributes
117+
└── generateDependsOnAttribute() ← Shared: depends_on generation
118+
```
119+
120+
**Resource Definition Callbacks** (`importable` struct in `exporter/model.go`):
121+
- `ShouldOmitFieldUnified` - Unified callback for field omission (works with both frameworks)
122+
- `ShouldGenerateFieldUnified` - Unified callback for field generation (works with both frameworks)
123+
- `ShouldOmitField` - Legacy SDKv2-only callback (deprecated, use Unified version)
124+
- `ShouldGenerateField` - Legacy SDKv2-only callback (deprecated, use Unified version)
125+
126+
**Key Differences**:
127+
- SDKv2 generates nested structures as **blocks**: `evaluation { ... }`
128+
- Plugin Framework generates nested structures as **attributes**: `evaluation = { ... }`
129+
130+
**When Adding Exporter Support**:
131+
1. Define resource in `exporter/importables.go` with `PluginFramework: true` for Plugin Framework resources
132+
2. Implement `List` function to discover resources
133+
3. Implement `Import` function to emit dependencies (use `convertPluginFrameworkToGoSdk` helper for Plugin Framework)
134+
4. Define `Depends` relationships for cross-resource references
135+
5. Use unified callbacks (`ShouldOmitFieldUnified`, `ShouldGenerateFieldUnified`) for custom field logic
136+
98137
### Dual-Provider Resource Patterns
99138

100139
#### Import Handling for Account/Workspace Resources

NEXT_CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,6 @@
1414

1515
### Exporter
1616

17+
* Initial support for resources implemented with plugin framework ([#5176](https://github.com/databricks/terraform-provider-databricks/pull/5176)).
18+
1719
### Internal Changes

docs/guides/experimental-exporter.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ Services could be specified in combination with predefined aliases (`all` - for
154154
-> Please note that for services not marked with **listing**, we'll export resources only if they are referenced from other resources.
155155

156156
* `access` - **listing** [databricks_permissions](../resources/permissions.md), [databricks_instance_profile](../resources/instance_profile.md), [databricks_ip_access_list](../resources/ip_access_list.md), and [databricks_access_control_rule_set](../resources/access_control_rule_set.md). *Please note that for `databricks_permissions` we list only `authorization = "tokens"`, the permissions for other objects (notebooks, ...) will be emitted when corresponding objects are processed!*
157-
* `alerts` - **listing** [databricks_alert](../resources/alert.md).
157+
* `alerts` - **listing** [databricks_alert](../resources/alert.md) and [databricks_alert_v2](../resources/alert_v2.md).
158158
* `billing` - **listing** [databricks_budget](../resources/budget.md).
159159
* `compute` - **listing** [databricks_cluster](../resources/cluster.md).
160160
* `dashboards` - **listing** [databricks_dashboard](../resources/dashboard.md).
@@ -219,6 +219,8 @@ Exporter aims to generate HCL code for most of the resources within the Databric
219219
| Resource | Supported | Incremental | Workspace | Account |
220220
| --- | --- | --- | --- | --- |
221221
| [databricks_access_control_rule_set](../resources/access_control_rule_set.md) | Yes | No | No | Yes |
222+
| [databricks_alert](../resources/alert.md) | Yes | Yes | Yes | No |
223+
| [databricks_alert_v2](../resources/alert_v2.md) | Yes | Yes | Yes | No |
222224
| [databricks_artifact_allowlist](../resources/artifact_allowlist.md) | Yes | No | Yes | No |
223225
| [databricks_budget](../resources/budget.md) | Yes | Yes | No | Yes |
224226
| [databricks_catalog](../resources/catalog.md) | Yes | Yes | Yes | No |
@@ -264,6 +266,7 @@ Exporter aims to generate HCL code for most of the resources within the Databric
264266
| [databricks_online_table](../resources/online_table.md) | Yes | Yes | Yes | No |
265267
| [databricks_permissions](../resources/permissions.md) | Yes | No | Yes | No |
266268
| [databricks_pipeline](../resources/pipeline.md) | Yes | Yes | Yes | No |
269+
| [databricks_query](../resources/query.md) | Yes | Yes | Yes | No |
267270
| [databricks_recipient](../resources/recipient.md) | Yes | Yes | Yes | No |
268271
| [databricks_registered_model](../resources/registered.md) | Yes | Yes | Yes | No |
269272
| [databricks_repo](../resources/repo.md) | Yes | No | Yes | No |

0 commit comments

Comments
 (0)