From 6d13dd172e75624ef9724c736baf03d60c5b6169 Mon Sep 17 00:00:00 2001 From: Tanmay Rustagi Date: Tue, 21 Oct 2025 18:04:28 +0530 Subject: [PATCH 1/8] [Feature] --- NEXT_CHANGELOG.md | 2 ++ common/client.go | 71 ++++++++++++++++++++++++++--------------------- 2 files changed, 42 insertions(+), 31 deletions(-) diff --git a/NEXT_CHANGELOG.md b/NEXT_CHANGELOG.md index 0186812101..e0b9a44a9b 100644 --- a/NEXT_CHANGELOG.md +++ b/NEXT_CHANGELOG.md @@ -6,6 +6,8 @@ ### New Features and Improvements +* Add `provider_config` support for manual plugin framework resources and data sources([#5115](https://github.com/databricks/terraform-provider-databricks/pull/5115)) + ### Bug Fixes * Fix crash when error happens during reading `databricks_job` ([#5110](https://github.com/databricks/terraform-provider-databricks/pull/5110)) diff --git a/common/client.go b/common/client.go index 53400261be..a9919c7d21 100644 --- a/common/client.go +++ b/common/client.go @@ -77,12 +77,29 @@ type DatabricksClient struct { mu sync.Mutex } +// GetWorkspaceClientForUnifiedProviderWithDiagnostics returns the Databricks +// WorkspaceClient for workspace level resources or diagnostics if that fails +// for terraform provider, the provider can be configured at account level or workspace level. +// This implementation will be used by resources and data sources that are developed +// over plugin framework. +func (c *DatabricksClient) GetWorkspaceClientForUnifiedProviderWithDiagnostics( + ctx context.Context, workspaceID string, +) (*databricks.WorkspaceClient, diag.Diagnostics) { + w, err := c.GetWorkspaceClientForUnifiedProvider(ctx, workspaceID) + if err != nil { + return nil, diag.Diagnostics{diag.NewErrorDiagnostic("failed to get workspace client", err.Error())} + } + return w, nil +} + // GetWorkspaceClientForUnifiedProvider returns the Databricks // WorkspaceClient for workspace level resources or diagnostics if that fails // for terraform provider, the provider can be configured at account level or workspace level. +// This implementation will be used by resources and data sources that are developed +// over SDKv2. func (c *DatabricksClient) GetWorkspaceClientForUnifiedProvider( ctx context.Context, workspaceID string, -) (*databricks.WorkspaceClient, diag.Diagnostics) { +) (*databricks.WorkspaceClient, error) { // The provider can be configured at account level or workspace level. if c.Config.IsAccountClient() { return c.getWorkspaceClientForAccountConfiguredProvider(ctx, workspaceID) @@ -95,28 +112,24 @@ func (c *DatabricksClient) GetWorkspaceClientForUnifiedProvider( // at account level. func (c *DatabricksClient) getWorkspaceClientForAccountConfiguredProvider( ctx context.Context, workspaceID string, -) (*databricks.WorkspaceClient, diag.Diagnostics) { +) (*databricks.WorkspaceClient, error) { // Workspace ID must be set in a workspace level resource if // the provider is configured at account level. // TODO: Link to the documentation once migration guide is published if workspaceID == "" { - return nil, diag.Diagnostics{diag.NewErrorDiagnostic( - "workspace_id is not set", - "please set the workspace_id in the provider_config")} + return nil, fmt.Errorf("workspace_id is not set, please set the workspace_id in the provider_config") } // Parse the workspace ID to int. - workspaceIDInt, diags := parseWorkspaceID(workspaceID) - if diags.HasError() { - return nil, diags + workspaceIDInt, err := parseWorkspaceID(workspaceID) + if err != nil { + return nil, err } // Get the workspace client for the workspace ID. w, err := c.WorkspaceClientForWorkspace(ctx, workspaceIDInt) if err != nil { - diags.AddError(fmt.Sprintf( - "failed to get workspace client with workspace_id %d", workspaceIDInt), err.Error()) - return nil, diags + return nil, fmt.Errorf("failed to get workspace client with workspace_id %d: %w", workspaceIDInt, err) } return w, nil } @@ -125,44 +138,40 @@ func (c *DatabricksClient) getWorkspaceClientForAccountConfiguredProvider( // the workspace ID specified in the resource when the provider is configured at workspace level. func (c *DatabricksClient) getWorkspaceClientForWorkspaceConfiguredProvider( ctx context.Context, workspaceID string, -) (*databricks.WorkspaceClient, diag.Diagnostics) { +) (*databricks.WorkspaceClient, error) { // Provider is configured at workspace level and we get the // workspace client from the provider. if workspaceID == "" { - return c.GetWorkspaceClient() + return c.WorkspaceClient() } - workspaceIDInt, diags := parseWorkspaceID(workspaceID) - if diags.HasError() { - return nil, diags + workspaceIDInt, err := parseWorkspaceID(workspaceID) + if err != nil { + return nil, err } // Check if the workspace ID specified in the resource matches // the workspace ID of the provider configured workspace client. - w, clientDiags := c.GetWorkspaceClient() - diags.Append(clientDiags...) - if diags.HasError() { - return nil, diags + w, err := c.WorkspaceClient() + if err != nil { + return nil, err } - err := c.validateWorkspaceIDFromProvider(ctx, workspaceIDInt, w) + + err = c.validateWorkspaceIDFromProvider(ctx, workspaceIDInt, w) if err != nil { - diags.AddError("failed to validate workspace_id", err.Error()) - return nil, diags + return nil, fmt.Errorf("failed to validate workspace_id: %w", err) } // The provider is configured at the workspace level and the // workspace ID matches - return w, diags + return w, nil } // parseWorkspaceID parses the workspace ID from string to int64. -func parseWorkspaceID(workspaceID string) (int64, diag.Diagnostics) { +func parseWorkspaceID(workspaceID string) (int64, error) { workspaceIDInt, err := strconv.ParseInt(workspaceID, 10, 64) if err != nil { - return 0, diag.Diagnostics{ - diag.NewErrorDiagnostic( - "failed to parse workspace_id. please check if the workspace_id in provider_config is a valid integer", err.Error(), - ), - } + return 0, fmt.Errorf("failed to parse workspace_id, please check if the workspace_id in provider_config is a valid integer: %w", err) + } return workspaceIDInt, nil } @@ -182,7 +191,7 @@ func (c *DatabricksClient) validateWorkspaceIDFromProvider(ctx context.Context, if c.cachedWorkspaceID != workspaceID { return fmt.Errorf("workspace_id mismatch: provider is configured for workspace %d but got %d in provider_config. "+ - "Please check the workspace_id provided in provider_config", + "please check the workspace_id provided in provider_config", c.cachedWorkspaceID, workspaceID) } return nil From 61313af5619d76e0c2465065ed85e62d07991100 Mon Sep 17 00:00:00 2001 From: Tanmay Rustagi Date: Tue, 21 Oct 2025 18:22:50 +0530 Subject: [PATCH 2/8] - --- .../pluginfw/products/app/data_app.go | 38 +++++-- .../pluginfw/products/app/data_apps.go | 33 +++++- .../pluginfw/products/app/resource_app.go | 104 +++++++++++++++--- .../products/catalog/data_functions.go | 36 ++++-- .../pluginfw/products/cluster/data_cluster.go | 35 ++++-- .../products/dashboards/data_dashboards.go | 28 ++++- .../data_notification_destinations.go | 28 ++++- .../registered_model/data_registered_model.go | 33 ++++-- .../data_registered_model_versions.go | 30 ++++- .../serving/data_serving_endpoints.go | 29 ++++- .../pluginfw/products/volume/data_volumes.go | 38 +++++-- .../pluginfw/tfschema/unified_provider.go | 9 ++ 12 files changed, 349 insertions(+), 92 deletions(-) diff --git a/internal/providers/pluginfw/products/app/data_app.go b/internal/providers/pluginfw/products/app/data_app.go index 2d36537fa0..1f2584e185 100644 --- a/internal/providers/pluginfw/products/app/data_app.go +++ b/internal/providers/pluginfw/products/app/data_app.go @@ -11,8 +11,8 @@ import ( "github.com/databricks/terraform-provider-databricks/internal/providers/pluginfw/tfschema" "github.com/databricks/terraform-provider-databricks/internal/service/apps_tf" "github.com/hashicorp/terraform-plugin-framework/datasource" - "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) func DataSourceApp() datasource.DataSource { @@ -24,20 +24,22 @@ type dataSourceApp struct { } type dataApp struct { - Name types.String `tfsdk:"name"` - App types.Object `tfsdk:"app"` + Name types.String `tfsdk:"name"` + App types.Object `tfsdk:"app"` + ProviderConfigData types.Object `tfsdk:"provider_config"` } func (dataApp) ApplySchemaCustomizations(attrs map[string]tfschema.AttributeBuilder) map[string]tfschema.AttributeBuilder { attrs["name"] = attrs["name"].SetRequired() attrs["app"] = attrs["app"].SetComputed() - + attrs["provider_config"] = attrs["provider_config"].SetOptional() return attrs } func (dataApp) GetComplexFieldTypes(context.Context) map[string]reflect.Type { return map[string]reflect.Type{ - "app": reflect.TypeOf(apps_tf.App{}), + "app": reflect.TypeOf(apps_tf.App{}), + "provider_config": reflect.TypeOf(tfschema.ProviderConfigData{}), } } @@ -59,19 +61,33 @@ func (a *dataSourceApp) Configure(ctx context.Context, req datasource.ConfigureR func (a *dataSourceApp) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { ctx = pluginfwcontext.SetUserAgentInDataSourceContext(ctx, resourceName) - w, diags := a.client.GetWorkspaceClient() - resp.Diagnostics.Append(diags...) + + var config dataApp + resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) if resp.Diagnostics.HasError() { return } - var name types.String - resp.Diagnostics.Append(req.Config.GetAttribute(ctx, path.Root("name"), &name)...) + var workspaceID string + if !config.ProviderConfigData.IsNull() { + var namespace tfschema.ProviderConfigData + resp.Diagnostics.Append(config.ProviderConfigData.As(ctx, &namespace, basetypes.ObjectAsOptions{ + UnhandledNullAsEmpty: true, + UnhandledUnknownAsEmpty: true, + })...) + if resp.Diagnostics.HasError() { + return + } + workspaceID = namespace.WorkspaceID.ValueString() + } + + w, diags := a.client.GetWorkspaceClientForUnifiedProviderWithDiagnostics(ctx, workspaceID) + resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { return } - appGoSdk, err := w.Apps.GetByName(ctx, name.ValueString()) + appGoSdk, err := w.Apps.GetByName(ctx, config.Name.ValueString()) if err != nil { resp.Diagnostics.AddError("failed to read app", err.Error()) return @@ -82,7 +98,7 @@ func (a *dataSourceApp) Read(ctx context.Context, req datasource.ReadRequest, re if resp.Diagnostics.HasError() { return } - dataApp := dataApp{Name: name, App: newApp.ToObjectValue(ctx)} + dataApp := dataApp{Name: config.Name, App: newApp.ToObjectValue(ctx), ProviderConfigData: config.ProviderConfigData} resp.Diagnostics.Append(resp.State.Set(ctx, dataApp)...) if resp.Diagnostics.HasError() { return diff --git a/internal/providers/pluginfw/products/app/data_apps.go b/internal/providers/pluginfw/products/app/data_apps.go index 19ebeeb6ed..a4f149d7b1 100644 --- a/internal/providers/pluginfw/products/app/data_apps.go +++ b/internal/providers/pluginfw/products/app/data_apps.go @@ -14,6 +14,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/datasource" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) func DataSourceApps() datasource.DataSource { @@ -25,18 +26,20 @@ type dataSourceApps struct { } type dataApps struct { - Apps types.List `tfsdk:"app"` + Apps types.List `tfsdk:"app"` + ProviderConfigData types.Object `tfsdk:"provider_config"` } func (dataApps) ApplySchemaCustomizations(attrs map[string]tfschema.AttributeBuilder) map[string]tfschema.AttributeBuilder { attrs["app"] = attrs["app"].SetComputed() - + attrs["provider_config"] = attrs["provider_config"].SetOptional() return attrs } func (dataApps) GetComplexFieldTypes(context.Context) map[string]reflect.Type { return map[string]reflect.Type{ - "app": reflect.TypeOf(apps_tf.App{}), + "app": reflect.TypeOf(apps_tf.App{}), + "provider_config": reflect.TypeOf(tfschema.ProviderConfigData{}), } } @@ -58,7 +61,27 @@ func (a *dataSourceApps) Configure(ctx context.Context, req datasource.Configure func (a *dataSourceApps) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { ctx = pluginfwcontext.SetUserAgentInDataSourceContext(ctx, resourceName) - w, diags := a.client.GetWorkspaceClient() + + var config dataApps + resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) + if resp.Diagnostics.HasError() { + return + } + + var workspaceID string + if !config.ProviderConfigData.IsNull() { + var namespace tfschema.ProviderConfigData + resp.Diagnostics.Append(config.ProviderConfigData.As(ctx, &namespace, basetypes.ObjectAsOptions{ + UnhandledNullAsEmpty: true, + UnhandledUnknownAsEmpty: true, + })...) + if resp.Diagnostics.HasError() { + return + } + workspaceID = namespace.WorkspaceID.ValueString() + } + + w, diags := a.client.GetWorkspaceClientForUnifiedProviderWithDiagnostics(ctx, workspaceID) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { return @@ -79,7 +102,7 @@ func (a *dataSourceApps) Read(ctx context.Context, req datasource.ReadRequest, r } apps = append(apps, app.ToObjectValue(ctx)) } - dataApps := dataApps{Apps: types.ListValueMust(apps_tf.App{}.Type(ctx), apps)} + dataApps := dataApps{Apps: types.ListValueMust(apps_tf.App{}.Type(ctx), apps), ProviderConfigData: config.ProviderConfigData} resp.Diagnostics.Append(resp.State.Set(ctx, dataApps)...) if resp.Diagnostics.HasError() { return diff --git a/internal/providers/pluginfw/products/app/resource_app.go b/internal/providers/pluginfw/products/app/resource_app.go index d3fe6c3377..b13f513c16 100644 --- a/internal/providers/pluginfw/products/app/resource_app.go +++ b/internal/providers/pluginfw/products/app/resource_app.go @@ -22,6 +22,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64planmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) const ( @@ -31,16 +32,24 @@ const ( type appResource struct { apps_tf.App - NoCompute types.Bool `tfsdk:"no_compute"` + NoCompute types.Bool `tfsdk:"no_compute"` + ProviderConfig types.Object `tfsdk:"provider_config"` } func (a appResource) ApplySchemaCustomizations(s map[string]tfschema.AttributeBuilder) map[string]tfschema.AttributeBuilder { s["no_compute"] = s["no_compute"].SetOptional() + s["provider_config"] = s["provider_config"].SetOptional() s["compute_size"] = s["compute_size"].SetComputed() s = apps_tf.App{}.ApplySchemaCustomizations(s) return s } +func (a appResource) GetComplexFieldTypes(ctx context.Context) map[string]reflect.Type { + attrs := a.App.GetComplexFieldTypes(ctx) + attrs["provider_config"] = reflect.TypeOf(tfschema.ProviderConfig{}) + return attrs +} + func ResourceApp() resource.Resource { return &resourceApp{} } @@ -94,17 +103,32 @@ func (a *resourceApp) Configure(ctx context.Context, req resource.ConfigureReque func (a *resourceApp) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { ctx = pluginfwcontext.SetUserAgentInResourceContext(ctx, resourceName) - w, diags := a.client.GetWorkspaceClient() - resp.Diagnostics.Append(diags...) + + var app appResource + resp.Diagnostics.Append(req.Plan.Get(ctx, &app)...) if resp.Diagnostics.HasError() { return } - var app appResource - resp.Diagnostics.Append(req.Plan.Get(ctx, &app)...) + var workspaceID string + if !app.ProviderConfig.IsNull() { + var namespace tfschema.ProviderConfigData + resp.Diagnostics.Append(app.ProviderConfig.As(ctx, &namespace, basetypes.ObjectAsOptions{ + UnhandledNullAsEmpty: true, + UnhandledUnknownAsEmpty: true, + })...) + if resp.Diagnostics.HasError() { + return + } + workspaceID = namespace.WorkspaceID.ValueString() + } + + w, diags := a.client.GetWorkspaceClientForUnifiedProviderWithDiagnostics(ctx, workspaceID) + resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { return } + var appGoSdk apps.App resp.Diagnostics.Append(converters.TfSdkToGoSdkStruct(ctx, app, &appGoSdk)...) if resp.Diagnostics.HasError() { @@ -133,6 +157,7 @@ func (a *resourceApp) Create(ctx context.Context, req resource.CreateRequest, re return } newApp.NoCompute = app.NoCompute + newApp.ProviderConfig = app.ProviderConfig resp.Diagnostics.Append(resp.State.Set(ctx, newApp)...) if resp.Diagnostics.HasError() { return @@ -150,6 +175,7 @@ func (a *resourceApp) Create(ctx context.Context, req resource.CreateRequest, re if resp.Diagnostics.HasError() { return } + newApp.ProviderConfig = app.ProviderConfig resp.Diagnostics.Append(resp.State.Set(ctx, newApp)...) if resp.Diagnostics.HasError() { return @@ -195,14 +221,28 @@ func (a *resourceApp) waitForApp(ctx context.Context, w *databricks.WorkspaceCli func (a *resourceApp) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { ctx = pluginfwcontext.SetUserAgentInResourceContext(ctx, resourceName) - w, diags := a.client.GetWorkspaceClient() - resp.Diagnostics.Append(diags...) + + var app appResource + resp.Diagnostics.Append(req.State.Get(ctx, &app)...) if resp.Diagnostics.HasError() { return } - var app appResource - resp.Diagnostics.Append(req.State.Get(ctx, &app)...) + var workspaceID string + if !app.ProviderConfig.IsNull() { + var namespace tfschema.ProviderConfigData + resp.Diagnostics.Append(app.ProviderConfig.As(ctx, &namespace, basetypes.ObjectAsOptions{ + UnhandledNullAsEmpty: true, + UnhandledUnknownAsEmpty: true, + })...) + if resp.Diagnostics.HasError() { + return + } + workspaceID = namespace.WorkspaceID.ValueString() + } + + w, diags := a.client.GetWorkspaceClientForUnifiedProviderWithDiagnostics(ctx, workspaceID) + resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { return } @@ -219,6 +259,7 @@ func (a *resourceApp) Read(ctx context.Context, req resource.ReadRequest, resp * return } newApp.NoCompute = app.NoCompute + newApp.ProviderConfig = app.ProviderConfig resp.Diagnostics.Append(resp.State.Set(ctx, newApp)...) if resp.Diagnostics.HasError() { return @@ -227,14 +268,28 @@ func (a *resourceApp) Read(ctx context.Context, req resource.ReadRequest, resp * func (a *resourceApp) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { ctx = pluginfwcontext.SetUserAgentInResourceContext(ctx, resourceName) - w, diags := a.client.GetWorkspaceClient() - resp.Diagnostics.Append(diags...) + + var app appResource + resp.Diagnostics.Append(req.Plan.Get(ctx, &app)...) if resp.Diagnostics.HasError() { return } - var app appResource - resp.Diagnostics.Append(req.Plan.Get(ctx, &app)...) + var workspaceID string + if !app.ProviderConfig.IsNull() { + var namespace tfschema.ProviderConfigData + resp.Diagnostics.Append(app.ProviderConfig.As(ctx, &namespace, basetypes.ObjectAsOptions{ + UnhandledNullAsEmpty: true, + UnhandledUnknownAsEmpty: true, + })...) + if resp.Diagnostics.HasError() { + return + } + workspaceID = namespace.WorkspaceID.ValueString() + } + + w, diags := a.client.GetWorkspaceClientForUnifiedProviderWithDiagnostics(ctx, workspaceID) + resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { return } @@ -259,6 +314,7 @@ func (a *resourceApp) Update(ctx context.Context, req resource.UpdateRequest, re } // Modifying no_compute after creation has no effect. newApp.NoCompute = app.NoCompute + newApp.ProviderConfig = app.ProviderConfig resp.Diagnostics.Append(resp.State.Set(ctx, newApp)...) if resp.Diagnostics.HasError() { return @@ -267,14 +323,28 @@ func (a *resourceApp) Update(ctx context.Context, req resource.UpdateRequest, re func (a *resourceApp) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { ctx = pluginfwcontext.SetUserAgentInResourceContext(ctx, resourceName) - w, diags := a.client.GetWorkspaceClient() - resp.Diagnostics.Append(diags...) + + var app appResource + resp.Diagnostics.Append(req.State.Get(ctx, &app)...) if resp.Diagnostics.HasError() { return } - var app appResource - resp.Diagnostics.Append(req.State.Get(ctx, &app)...) + var workspaceID string + if !app.ProviderConfig.IsNull() { + var namespace tfschema.ProviderConfigData + resp.Diagnostics.Append(app.ProviderConfig.As(ctx, &namespace, basetypes.ObjectAsOptions{ + UnhandledNullAsEmpty: true, + UnhandledUnknownAsEmpty: true, + })...) + if resp.Diagnostics.HasError() { + return + } + workspaceID = namespace.WorkspaceID.ValueString() + } + + w, diags := a.client.GetWorkspaceClientForUnifiedProviderWithDiagnostics(ctx, workspaceID) + resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { return } diff --git a/internal/providers/pluginfw/products/catalog/data_functions.go b/internal/providers/pluginfw/products/catalog/data_functions.go index c60b8a62b6..f610bd6412 100644 --- a/internal/providers/pluginfw/products/catalog/data_functions.go +++ b/internal/providers/pluginfw/products/catalog/data_functions.go @@ -17,6 +17,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/datasource" "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) const dataSourceName = "functions" @@ -32,10 +33,11 @@ type FunctionsDataSource struct { } type FunctionsData struct { - CatalogName types.String `tfsdk:"catalog_name"` - SchemaName types.String `tfsdk:"schema_name"` - IncludeBrowse types.Bool `tfsdk:"include_browse"` - Functions types.List `tfsdk:"functions"` + CatalogName types.String `tfsdk:"catalog_name"` + SchemaName types.String `tfsdk:"schema_name"` + IncludeBrowse types.Bool `tfsdk:"include_browse"` + Functions types.List `tfsdk:"functions"` + ProviderConfigData types.Object `tfsdk:"provider_config"` } func (FunctionsData) ApplySchemaCustomizations(attrs map[string]tfschema.AttributeBuilder) map[string]tfschema.AttributeBuilder { @@ -43,13 +45,14 @@ func (FunctionsData) ApplySchemaCustomizations(attrs map[string]tfschema.Attribu attrs["schema_name"] = attrs["schema_name"].SetRequired() attrs["include_browse"] = attrs["include_browse"].SetOptional() attrs["functions"] = attrs["functions"].SetOptional().SetComputed() - + attrs["provider_config"] = attrs["provider_config"].SetOptional() return attrs } func (FunctionsData) GetComplexFieldTypes(context.Context) map[string]reflect.Type { return map[string]reflect.Type{ - "functions": reflect.TypeOf(catalog_tf.FunctionInfo{}), + "functions": reflect.TypeOf(catalog_tf.FunctionInfo{}), + "provider_config": reflect.TypeOf(tfschema.ProviderConfigData{}), } } @@ -73,18 +76,33 @@ func (d *FunctionsDataSource) Configure(_ context.Context, req datasource.Config func (d *FunctionsDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { ctx = pluginfwcontext.SetUserAgentInDataSourceContext(ctx, dataSourceName) - w, diags := d.Client.GetWorkspaceClient() + + var functions FunctionsData + diags := req.Config.Get(ctx, &functions) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { return } - var functions FunctionsData - diags = req.Config.Get(ctx, &functions) + var workspaceID string + if !functions.ProviderConfigData.IsNull() { + var namespace tfschema.ProviderConfigData + resp.Diagnostics.Append(functions.ProviderConfigData.As(ctx, &namespace, basetypes.ObjectAsOptions{ + UnhandledNullAsEmpty: true, + UnhandledUnknownAsEmpty: true, + })...) + if resp.Diagnostics.HasError() { + return + } + workspaceID = namespace.WorkspaceID.ValueString() + } + + w, diags := d.Client.GetWorkspaceClientForUnifiedProviderWithDiagnostics(ctx, workspaceID) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { return } + catalogName := functions.CatalogName.ValueString() schemaName := functions.SchemaName.ValueString() functionsInfosSdk, err := w.Functions.ListAll(ctx, catalog.ListFunctionsRequest{ diff --git a/internal/providers/pluginfw/products/cluster/data_cluster.go b/internal/providers/pluginfw/products/cluster/data_cluster.go index e43740f3b3..315c3e5024 100644 --- a/internal/providers/pluginfw/products/cluster/data_cluster.go +++ b/internal/providers/pluginfw/products/cluster/data_cluster.go @@ -19,6 +19,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) const dataSourceName = "cluster" @@ -34,22 +35,24 @@ type ClusterDataSource struct { } type ClusterInfo struct { - ClusterId types.String `tfsdk:"cluster_id"` - Name types.String `tfsdk:"cluster_name"` - ClusterInfo types.List `tfsdk:"cluster_info"` + ClusterId types.String `tfsdk:"cluster_id"` + Name types.String `tfsdk:"cluster_name"` + ClusterInfo types.List `tfsdk:"cluster_info"` + ProviderConfigData types.Object `tfsdk:"provider_config"` } func (ClusterInfo) ApplySchemaCustomizations(attrs map[string]tfschema.AttributeBuilder) map[string]tfschema.AttributeBuilder { attrs["cluster_id"] = attrs["cluster_id"].SetOptional().SetComputed() attrs["cluster_name"] = attrs["cluster_name"].SetOptional().SetComputed() attrs["cluster_info"] = attrs["cluster_info"].SetOptional().SetComputed() - + attrs["provider_config"] = attrs["provider_config"].SetOptional() return attrs } func (ClusterInfo) GetComplexFieldTypes(context.Context) map[string]reflect.Type { return map[string]reflect.Type{ - "cluster_info": reflect.TypeOf(compute_tf.ClusterDetails_SdkV2{}), + "cluster_info": reflect.TypeOf(compute_tf.ClusterDetails_SdkV2{}), + "provider_config": reflect.TypeOf(tfschema.ProviderConfigData{}), } } @@ -73,14 +76,28 @@ func (d *ClusterDataSource) Configure(_ context.Context, req datasource.Configur func (d *ClusterDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { ctx = pluginfwcontext.SetUserAgentInDataSourceContext(ctx, dataSourceName) - w, diags := d.Client.GetWorkspaceClient() - resp.Diagnostics.Append(diags...) + + var clusterInfo ClusterInfo + resp.Diagnostics.Append(req.Config.Get(ctx, &clusterInfo)...) if resp.Diagnostics.HasError() { return } - var clusterInfo ClusterInfo - resp.Diagnostics.Append(req.Config.Get(ctx, &clusterInfo)...) + var workspaceID string + if !clusterInfo.ProviderConfigData.IsNull() { + var namespace tfschema.ProviderConfigData + resp.Diagnostics.Append(clusterInfo.ProviderConfigData.As(ctx, &namespace, basetypes.ObjectAsOptions{ + UnhandledNullAsEmpty: true, + UnhandledUnknownAsEmpty: true, + })...) + if resp.Diagnostics.HasError() { + return + } + workspaceID = namespace.WorkspaceID.ValueString() + } + + w, diags := d.Client.GetWorkspaceClientForUnifiedProviderWithDiagnostics(ctx, workspaceID) + resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { return } diff --git a/internal/providers/pluginfw/products/dashboards/data_dashboards.go b/internal/providers/pluginfw/products/dashboards/data_dashboards.go index 52b7b0603b..e27a7d25bd 100644 --- a/internal/providers/pluginfw/products/dashboards/data_dashboards.go +++ b/internal/providers/pluginfw/products/dashboards/data_dashboards.go @@ -17,6 +17,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) const dataSourceName = "dashboards" @@ -34,18 +35,20 @@ type DashboardsDataSource struct { type DashboardsInfo struct { DashboardNameContains types.String `tfsdk:"dashboard_name_contains"` Dashboards types.List `tfsdk:"dashboards"` + ProviderConfig types.Object `tfsdk:"provider_config"` } func (DashboardsInfo) ApplySchemaCustomizations(attrs map[string]tfschema.AttributeBuilder) map[string]tfschema.AttributeBuilder { attrs["dashboard_name_contains"] = attrs["dashboard_name_contains"].SetOptional() attrs["dashboards"] = attrs["dashboards"].SetComputed() - + attrs["provider_config"] = attrs["provider_config"].SetOptional() return attrs } func (DashboardsInfo) GetComplexFieldTypes(context.Context) map[string]reflect.Type { return map[string]reflect.Type{ - "dashboards": reflect.TypeOf(dashboards_tf.Dashboard{}), + "dashboards": reflect.TypeOf(dashboards_tf.Dashboard{}), + "provider_config": reflect.TypeOf(tfschema.ProviderConfigData{}), } } @@ -74,15 +77,28 @@ func AppendDiagAndCheckErrors(resp *datasource.ReadResponse, diags diag.Diagnost func (d *DashboardsDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { ctx = pluginfwcontext.SetUserAgentInDataSourceContext(ctx, dataSourceName) - w, diags := d.Client.GetWorkspaceClient() - if AppendDiagAndCheckErrors(resp, diags) { - return - } var dashboardInfo DashboardsInfo if AppendDiagAndCheckErrors(resp, req.Config.Get(ctx, &dashboardInfo)) { return } + var workspaceID string + if !dashboardInfo.ProviderConfig.IsNull() { + var namespace tfschema.ProviderConfigData + resp.Diagnostics.Append(dashboardInfo.ProviderConfig.As(ctx, &namespace, basetypes.ObjectAsOptions{ + UnhandledNullAsEmpty: true, + UnhandledUnknownAsEmpty: true, + })...) + if resp.Diagnostics.HasError() { + return + } + workspaceID = namespace.WorkspaceID.ValueString() + } + w, diags := d.Client.GetWorkspaceClientForUnifiedProviderWithDiagnostics(ctx, workspaceID) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } dashboardName := strings.ToLower(dashboardInfo.DashboardNameContains.ValueString()) diff --git a/internal/providers/pluginfw/products/notificationdestinations/data_notification_destinations.go b/internal/providers/pluginfw/products/notificationdestinations/data_notification_destinations.go index 1d5f5d6b7b..1c4c167db4 100755 --- a/internal/providers/pluginfw/products/notificationdestinations/data_notification_destinations.go +++ b/internal/providers/pluginfw/products/notificationdestinations/data_notification_destinations.go @@ -19,6 +19,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) const dataSourceName = "notification_destinations" @@ -37,19 +38,21 @@ type NotificationDestinationsInfo struct { DisplayNameContains types.String `tfsdk:"display_name_contains"` Type types.String `tfsdk:"type"` NotificationDestinations types.List `tfsdk:"notification_destinations"` + ProviderConfigData types.Object `tfsdk:"provider_config"` } func (NotificationDestinationsInfo) ApplySchemaCustomizations(attrs map[string]tfschema.AttributeBuilder) map[string]tfschema.AttributeBuilder { attrs["display_name_contains"] = attrs["display_name_contains"].SetOptional() attrs["type"] = attrs["type"].SetOptional() attrs["notification_destinations"] = attrs["notification_destinations"].SetComputed() - + attrs["provider_config"] = attrs["provider_config"].SetOptional() return attrs } func (NotificationDestinationsInfo) GetComplexFieldTypes(context.Context) map[string]reflect.Type { return map[string]reflect.Type{ "notification_destinations": reflect.TypeOf(settings_tf.ListNotificationDestinationsResult{}), + "provider_config": reflect.TypeOf(tfschema.ProviderConfigData{}), } } @@ -93,16 +96,31 @@ func AppendDiagAndCheckErrors(resp *datasource.ReadResponse, diags diag.Diagnost func (d *NotificationDestinationsDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { ctx = pluginfwcontext.SetUserAgentInDataSourceContext(ctx, dataSourceName) - w, diags := d.Client.GetWorkspaceClient() - if AppendDiagAndCheckErrors(resp, diags) { - return - } var notificationInfo NotificationDestinationsInfo if AppendDiagAndCheckErrors(resp, req.Config.Get(ctx, ¬ificationInfo)) { return } + var workspaceID string + if !notificationInfo.ProviderConfigData.IsNull() { + var namespace tfschema.ProviderConfigData + resp.Diagnostics.Append(notificationInfo.ProviderConfigData.As(ctx, &namespace, basetypes.ObjectAsOptions{ + UnhandledNullAsEmpty: true, + UnhandledUnknownAsEmpty: true, + })...) + if resp.Diagnostics.HasError() { + return + } + workspaceID = namespace.WorkspaceID.ValueString() + } + + w, diags := d.Client.GetWorkspaceClientForUnifiedProviderWithDiagnostics(ctx, workspaceID) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + notificationType := notificationInfo.Type.ValueString() notificationDisplayName := strings.ToLower(notificationInfo.DisplayNameContains.ValueString()) diff --git a/internal/providers/pluginfw/products/registered_model/data_registered_model.go b/internal/providers/pluginfw/products/registered_model/data_registered_model.go index 6dd8257b74..adc1941446 100644 --- a/internal/providers/pluginfw/products/registered_model/data_registered_model.go +++ b/internal/providers/pluginfw/products/registered_model/data_registered_model.go @@ -34,10 +34,11 @@ type RegisteredModelDataSource struct { } type RegisteredModelData struct { - FullName types.String `tfsdk:"full_name"` - IncludeAliases types.Bool `tfsdk:"include_aliases"` - IncludeBrowse types.Bool `tfsdk:"include_browse"` - ModelInfo types.List `tfsdk:"model_info"` + FullName types.String `tfsdk:"full_name"` + IncludeAliases types.Bool `tfsdk:"include_aliases"` + IncludeBrowse types.Bool `tfsdk:"include_browse"` + ModelInfo types.List `tfsdk:"model_info"` + ProviderConfigData types.Object `tfsdk:"provider_config"` } func (RegisteredModelData) ApplySchemaCustomizations(attrs map[string]tfschema.AttributeBuilder) map[string]tfschema.AttributeBuilder { @@ -45,12 +46,14 @@ func (RegisteredModelData) ApplySchemaCustomizations(attrs map[string]tfschema.A attrs["include_aliases"] = attrs["include_aliases"].SetOptional() attrs["include_browse"] = attrs["include_browse"].SetOptional() attrs["model_info"] = attrs["model_info"].SetOptional().SetComputed() + attrs["provider_config"] = attrs["provider_config"].SetOptional() return attrs } func (RegisteredModelData) GetComplexFieldTypes(context.Context) map[string]reflect.Type { return map[string]reflect.Type{ - "model_info": reflect.TypeOf(catalog_tf.RegisteredModelInfo_SdkV2{}), + "model_info": reflect.TypeOf(catalog_tf.RegisteredModelInfo_SdkV2{}), + "provider_config": reflect.TypeOf(tfschema.ProviderConfigData{}), } } @@ -74,14 +77,28 @@ func (d *RegisteredModelDataSource) Configure(_ context.Context, req datasource. func (d *RegisteredModelDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { ctx = pluginfwcontext.SetUserAgentInDataSourceContext(ctx, dataSourceName) - w, diags := d.Client.GetWorkspaceClient() + + var registeredModel RegisteredModelData + diags := req.Config.Get(ctx, ®isteredModel) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { return } - var registeredModel RegisteredModelData - diags = req.Config.Get(ctx, ®isteredModel) + var workspaceID string + if !registeredModel.ProviderConfigData.IsNull() { + var namespace tfschema.ProviderConfigData + resp.Diagnostics.Append(registeredModel.ProviderConfigData.As(ctx, &namespace, basetypes.ObjectAsOptions{ + UnhandledNullAsEmpty: true, + UnhandledUnknownAsEmpty: true, + })...) + if resp.Diagnostics.HasError() { + return + } + workspaceID = namespace.WorkspaceID.ValueString() + } + + w, diags := d.Client.GetWorkspaceClientForUnifiedProviderWithDiagnostics(ctx, workspaceID) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { return diff --git a/internal/providers/pluginfw/products/registered_model/data_registered_model_versions.go b/internal/providers/pluginfw/products/registered_model/data_registered_model_versions.go index 3d17b589ae..7bf90f6aa7 100644 --- a/internal/providers/pluginfw/products/registered_model/data_registered_model_versions.go +++ b/internal/providers/pluginfw/products/registered_model/data_registered_model_versions.go @@ -14,6 +14,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/datasource" "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) func DataSourceRegisteredModelVersions() datasource.DataSource { @@ -27,19 +28,22 @@ type RegisteredModelVersionsDataSource struct { } type RegisteredModelVersionsData struct { - FullName types.String `tfsdk:"full_name"` - ModelVersions types.List `tfsdk:"model_versions"` + FullName types.String `tfsdk:"full_name"` + ModelVersions types.List `tfsdk:"model_versions"` + ProviderConfigData types.Object `tfsdk:"provider_config"` } func (RegisteredModelVersionsData) ApplySchemaCustomizations(attrs map[string]tfschema.AttributeBuilder) map[string]tfschema.AttributeBuilder { attrs["full_name"] = attrs["full_name"].SetRequired() attrs["model_versions"] = attrs["model_versions"].SetOptional().SetComputed() + attrs["provider_config"] = attrs["provider_config"].SetOptional() return attrs } func (RegisteredModelVersionsData) GetComplexFieldTypes(context.Context) map[string]reflect.Type { return map[string]reflect.Type{ - "model_versions": reflect.TypeOf(catalog_tf.ModelVersionInfo_SdkV2{}), + "model_versions": reflect.TypeOf(catalog_tf.ModelVersionInfo_SdkV2{}), + "provider_config": reflect.TypeOf(tfschema.ProviderConfigData{}), } } @@ -62,18 +66,32 @@ func (d *RegisteredModelVersionsDataSource) Configure(_ context.Context, req dat } func (d *RegisteredModelVersionsDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { - w, diags := d.Client.GetWorkspaceClient() + var registeredModelVersions RegisteredModelVersionsData + diags := req.Config.Get(ctx, ®isteredModelVersions) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { return } - var registeredModelVersions RegisteredModelVersionsData - diags = req.Config.Get(ctx, ®isteredModelVersions) + var workspaceID string + if !registeredModelVersions.ProviderConfigData.IsNull() { + var namespace tfschema.ProviderConfigData + resp.Diagnostics.Append(registeredModelVersions.ProviderConfigData.As(ctx, &namespace, basetypes.ObjectAsOptions{ + UnhandledNullAsEmpty: true, + UnhandledUnknownAsEmpty: true, + })...) + if resp.Diagnostics.HasError() { + return + } + workspaceID = namespace.WorkspaceID.ValueString() + } + + w, diags := d.Client.GetWorkspaceClientForUnifiedProviderWithDiagnostics(ctx, workspaceID) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { return } + modelFullName := registeredModelVersions.FullName.ValueString() modelVersions, err := w.ModelVersions.ListByFullName(ctx, modelFullName) if err != nil { diff --git a/internal/providers/pluginfw/products/serving/data_serving_endpoints.go b/internal/providers/pluginfw/products/serving/data_serving_endpoints.go index 53a95a070d..df0cd116b4 100644 --- a/internal/providers/pluginfw/products/serving/data_serving_endpoints.go +++ b/internal/providers/pluginfw/products/serving/data_serving_endpoints.go @@ -14,6 +14,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/datasource" "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) func DataSourceServingEndpoints() datasource.DataSource { @@ -27,18 +28,20 @@ type ServingEndpointsDataSource struct { } type ServingEndpointsData struct { - Endpoints types.List `tfsdk:"endpoints"` + Endpoints types.List `tfsdk:"endpoints"` + ProviderConfigData types.Object `tfsdk:"provider_config"` } func (ServingEndpointsData) ApplySchemaCustomizations(attrs map[string]tfschema.AttributeBuilder) map[string]tfschema.AttributeBuilder { attrs["endpoints"] = attrs["endpoints"].SetOptional().SetComputed() - + attrs["provider_config"] = attrs["provider_config"].SetOptional() return attrs } func (ServingEndpointsData) GetComplexFieldTypes(context.Context) map[string]reflect.Type { return map[string]reflect.Type{ - "endpoints": reflect.TypeOf(serving_tf.ServingEndpoint_SdkV2{}), + "endpoints": reflect.TypeOf(serving_tf.ServingEndpoint_SdkV2{}), + "provider_config": reflect.TypeOf(tfschema.ProviderConfigData{}), } } @@ -61,18 +64,32 @@ func (d *ServingEndpointsDataSource) Configure(_ context.Context, req datasource } func (d *ServingEndpointsDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { - w, diags := d.Client.GetWorkspaceClient() + var endpoints ServingEndpointsData + diags := req.Config.Get(ctx, &endpoints) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { return } - var endpoints ServingEndpointsData - diags = req.Config.Get(ctx, &endpoints) + var workspaceID string + if !endpoints.ProviderConfigData.IsNull() { + var namespace tfschema.ProviderConfigData + resp.Diagnostics.Append(endpoints.ProviderConfigData.As(ctx, &namespace, basetypes.ObjectAsOptions{ + UnhandledNullAsEmpty: true, + UnhandledUnknownAsEmpty: true, + })...) + if resp.Diagnostics.HasError() { + return + } + workspaceID = namespace.WorkspaceID.ValueString() + } + + w, diags := d.Client.GetWorkspaceClientForUnifiedProviderWithDiagnostics(ctx, workspaceID) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { return } + endpointsInfoSdk, err := w.ServingEndpoints.ListAll(ctx) if err != nil { if apierr.IsMissing(err) { diff --git a/internal/providers/pluginfw/products/volume/data_volumes.go b/internal/providers/pluginfw/products/volume/data_volumes.go index e5772cce4b..262e8b80ef 100644 --- a/internal/providers/pluginfw/products/volume/data_volumes.go +++ b/internal/providers/pluginfw/products/volume/data_volumes.go @@ -16,6 +16,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/datasource" "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) const dataSourceName = "volumes" @@ -31,21 +32,24 @@ type VolumesDataSource struct { } type VolumesList struct { - CatalogName types.String `tfsdk:"catalog_name"` - SchemaName types.String `tfsdk:"schema_name"` - Ids types.List `tfsdk:"ids"` + CatalogName types.String `tfsdk:"catalog_name"` + SchemaName types.String `tfsdk:"schema_name"` + Ids types.List `tfsdk:"ids"` + ProviderConfigData types.Object `tfsdk:"provider_config"` } func (VolumesList) ApplySchemaCustomizations(attrs map[string]tfschema.AttributeBuilder) map[string]tfschema.AttributeBuilder { attrs["catalog_name"] = attrs["catalog_name"].SetRequired() attrs["schema_name"] = attrs["schema_name"].SetRequired() attrs["ids"] = attrs["ids"].SetOptional().SetComputed() + attrs["provider_config"] = attrs["provider_config"].SetOptional() return attrs } func (VolumesList) GetComplexFieldTypes(context.Context) map[string]reflect.Type { return map[string]reflect.Type{ - "ids": reflect.TypeOf(types.String{}), + "ids": reflect.TypeOf(types.String{}), + "provider_config": reflect.TypeOf(tfschema.ProviderConfigData{}), } } @@ -69,20 +73,34 @@ func (d *VolumesDataSource) Configure(_ context.Context, req datasource.Configur func (d *VolumesDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { ctx = pluginfwcontext.SetUserAgentInDataSourceContext(ctx, dataSourceName) - w, diags := d.Client.GetWorkspaceClient() - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } var volumesList VolumesList - diags = req.Config.Get(ctx, &volumesList) + diags := req.Config.Get(ctx, &volumesList) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { return } var listVolumesRequest catalog.ListVolumesRequest converters.TfSdkToGoSdkStruct(ctx, volumesList, &listVolumesRequest) + + var workspaceID string + if !volumesList.ProviderConfigData.IsNull() { + var namespace tfschema.ProviderConfigData + resp.Diagnostics.Append(volumesList.ProviderConfigData.As(ctx, &namespace, basetypes.ObjectAsOptions{ + UnhandledNullAsEmpty: true, + UnhandledUnknownAsEmpty: true, + })...) + if resp.Diagnostics.HasError() { + return + } + workspaceID = namespace.WorkspaceID.ValueString() + } + w, clientDiags := d.Client.GetWorkspaceClientForUnifiedProviderWithDiagnostics(ctx, workspaceID) + resp.Diagnostics.Append(clientDiags...) + if resp.Diagnostics.HasError() { + return + } + volumes, err := w.Volumes.ListAll(ctx, listVolumesRequest) if err != nil { if apierr.IsMissing(err) { diff --git a/internal/providers/pluginfw/tfschema/unified_provider.go b/internal/providers/pluginfw/tfschema/unified_provider.go index aac9ffe1a2..6055cd11f4 100644 --- a/internal/providers/pluginfw/tfschema/unified_provider.go +++ b/internal/providers/pluginfw/tfschema/unified_provider.go @@ -3,6 +3,7 @@ package tfschema import ( "context" "reflect" + "regexp" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" "github.com/hashicorp/terraform-plugin-framework/attr" @@ -20,6 +21,10 @@ type Namespace struct { ProviderConfig types.Object `tfsdk:"provider_config"` } +type Namespace_SdkV2 struct { + ProviderConfig types.List `tfsdk:"provider_config"` +} + // ProviderConfig is used to store the provider configurations for unified terraform provider // across resources onboarded to plugin framework. type ProviderConfig struct { @@ -32,6 +37,8 @@ func (r ProviderConfig) ApplySchemaCustomizations(attrs map[string]AttributeBuil attrs["workspace_id"] = attrs["workspace_id"].(StringAttributeBuilder).AddPlanModifier( stringplanmodifier.RequiresReplaceIf(workspaceIDPlanModifier, "", "")) attrs["workspace_id"] = attrs["workspace_id"].(StringAttributeBuilder).AddValidator(stringvalidator.LengthAtLeast(1)) + attrs["workspace_id"] = attrs["workspace_id"].(StringAttributeBuilder).AddValidator( + stringvalidator.RegexMatches(regexp.MustCompile(`^\d+$`), "workspace_id must be a valid integer")) return attrs } @@ -81,6 +88,8 @@ type ProviderConfigData struct { func (r ProviderConfigData) ApplySchemaCustomizations(attrs map[string]AttributeBuilder) map[string]AttributeBuilder { attrs["workspace_id"] = attrs["workspace_id"].SetRequired() attrs["workspace_id"] = attrs["workspace_id"].(StringAttributeBuilder).AddValidator(stringvalidator.LengthAtLeast(1)) + attrs["workspace_id"] = attrs["workspace_id"].(StringAttributeBuilder).AddValidator( + stringvalidator.RegexMatches(regexp.MustCompile(`^\d+$`), "workspace_id must be a valid integer")) return attrs } From 10cb9341db482a54fac1a856c1768f8e8786f840 Mon Sep 17 00:00:00 2001 From: Tanmay Rustagi Date: Tue, 21 Oct 2025 18:35:34 +0530 Subject: [PATCH 3/8] - --- .../pluginfw/products/app/data_app.go | 18 ++++++++++++------ .../pluginfw/products/app/data_apps.go | 15 ++++++++++----- .../pluginfw/products/app/resource_app.go | 4 ++-- .../products/catalog/data_functions.go | 14 +++++++------- .../pluginfw/products/cluster/data_cluster.go | 12 ++++++------ .../products/dashboards/data_dashboards.go | 2 +- .../data_notification_destinations.go | 6 +++--- .../registered_model/data_registered_model.go | 14 +++++++------- .../data_registered_model_versions.go | 10 +++++----- .../products/serving/data_serving_endpoints.go | 8 ++++---- .../pluginfw/products/volume/data_volumes.go | 12 ++++++------ 11 files changed, 63 insertions(+), 52 deletions(-) diff --git a/internal/providers/pluginfw/products/app/data_app.go b/internal/providers/pluginfw/products/app/data_app.go index 1f2584e185..d0a7095a17 100644 --- a/internal/providers/pluginfw/products/app/data_app.go +++ b/internal/providers/pluginfw/products/app/data_app.go @@ -24,9 +24,9 @@ type dataSourceApp struct { } type dataApp struct { - Name types.String `tfsdk:"name"` - App types.Object `tfsdk:"app"` - ProviderConfigData types.Object `tfsdk:"provider_config"` + Name types.String `tfsdk:"name"` + App types.Object `tfsdk:"app"` + tfschema.Namespace } func (dataApp) ApplySchemaCustomizations(attrs map[string]tfschema.AttributeBuilder) map[string]tfschema.AttributeBuilder { @@ -69,9 +69,9 @@ func (a *dataSourceApp) Read(ctx context.Context, req datasource.ReadRequest, re } var workspaceID string - if !config.ProviderConfigData.IsNull() { + if !config.ProviderConfig.IsNull() { var namespace tfschema.ProviderConfigData - resp.Diagnostics.Append(config.ProviderConfigData.As(ctx, &namespace, basetypes.ObjectAsOptions{ + resp.Diagnostics.Append(config.ProviderConfig.As(ctx, &namespace, basetypes.ObjectAsOptions{ UnhandledNullAsEmpty: true, UnhandledUnknownAsEmpty: true, })...) @@ -98,7 +98,13 @@ func (a *dataSourceApp) Read(ctx context.Context, req datasource.ReadRequest, re if resp.Diagnostics.HasError() { return } - dataApp := dataApp{Name: config.Name, App: newApp.ToObjectValue(ctx), ProviderConfigData: config.ProviderConfigData} + dataApp := dataApp{ + Name: config.Name, + App: newApp.ToObjectValue(ctx), + Namespace: tfschema.Namespace{ + ProviderConfig: config.ProviderConfig, + }, + } resp.Diagnostics.Append(resp.State.Set(ctx, dataApp)...) if resp.Diagnostics.HasError() { return diff --git a/internal/providers/pluginfw/products/app/data_apps.go b/internal/providers/pluginfw/products/app/data_apps.go index a4f149d7b1..b174a114c5 100644 --- a/internal/providers/pluginfw/products/app/data_apps.go +++ b/internal/providers/pluginfw/products/app/data_apps.go @@ -26,8 +26,8 @@ type dataSourceApps struct { } type dataApps struct { - Apps types.List `tfsdk:"app"` - ProviderConfigData types.Object `tfsdk:"provider_config"` + Apps types.List `tfsdk:"app"` + tfschema.Namespace } func (dataApps) ApplySchemaCustomizations(attrs map[string]tfschema.AttributeBuilder) map[string]tfschema.AttributeBuilder { @@ -69,9 +69,9 @@ func (a *dataSourceApps) Read(ctx context.Context, req datasource.ReadRequest, r } var workspaceID string - if !config.ProviderConfigData.IsNull() { + if !config.ProviderConfig.IsNull() { var namespace tfschema.ProviderConfigData - resp.Diagnostics.Append(config.ProviderConfigData.As(ctx, &namespace, basetypes.ObjectAsOptions{ + resp.Diagnostics.Append(config.ProviderConfig.As(ctx, &namespace, basetypes.ObjectAsOptions{ UnhandledNullAsEmpty: true, UnhandledUnknownAsEmpty: true, })...) @@ -102,7 +102,12 @@ func (a *dataSourceApps) Read(ctx context.Context, req datasource.ReadRequest, r } apps = append(apps, app.ToObjectValue(ctx)) } - dataApps := dataApps{Apps: types.ListValueMust(apps_tf.App{}.Type(ctx), apps), ProviderConfigData: config.ProviderConfigData} + dataApps := dataApps{ + Apps: types.ListValueMust(apps_tf.App{}.Type(ctx), apps), + Namespace: tfschema.Namespace{ + ProviderConfig: config.ProviderConfig, + }, + } resp.Diagnostics.Append(resp.State.Set(ctx, dataApps)...) if resp.Diagnostics.HasError() { return diff --git a/internal/providers/pluginfw/products/app/resource_app.go b/internal/providers/pluginfw/products/app/resource_app.go index b13f513c16..bcdebb792c 100644 --- a/internal/providers/pluginfw/products/app/resource_app.go +++ b/internal/providers/pluginfw/products/app/resource_app.go @@ -32,8 +32,8 @@ const ( type appResource struct { apps_tf.App - NoCompute types.Bool `tfsdk:"no_compute"` - ProviderConfig types.Object `tfsdk:"provider_config"` + NoCompute types.Bool `tfsdk:"no_compute"` + tfschema.Namespace } func (a appResource) ApplySchemaCustomizations(s map[string]tfschema.AttributeBuilder) map[string]tfschema.AttributeBuilder { diff --git a/internal/providers/pluginfw/products/catalog/data_functions.go b/internal/providers/pluginfw/products/catalog/data_functions.go index f610bd6412..ce6164183c 100644 --- a/internal/providers/pluginfw/products/catalog/data_functions.go +++ b/internal/providers/pluginfw/products/catalog/data_functions.go @@ -33,11 +33,11 @@ type FunctionsDataSource struct { } type FunctionsData struct { - CatalogName types.String `tfsdk:"catalog_name"` - SchemaName types.String `tfsdk:"schema_name"` - IncludeBrowse types.Bool `tfsdk:"include_browse"` - Functions types.List `tfsdk:"functions"` - ProviderConfigData types.Object `tfsdk:"provider_config"` + CatalogName types.String `tfsdk:"catalog_name"` + SchemaName types.String `tfsdk:"schema_name"` + IncludeBrowse types.Bool `tfsdk:"include_browse"` + Functions types.List `tfsdk:"functions"` + tfschema.Namespace } func (FunctionsData) ApplySchemaCustomizations(attrs map[string]tfschema.AttributeBuilder) map[string]tfschema.AttributeBuilder { @@ -85,9 +85,9 @@ func (d *FunctionsDataSource) Read(ctx context.Context, req datasource.ReadReque } var workspaceID string - if !functions.ProviderConfigData.IsNull() { + if !functions.ProviderConfig.IsNull() { var namespace tfschema.ProviderConfigData - resp.Diagnostics.Append(functions.ProviderConfigData.As(ctx, &namespace, basetypes.ObjectAsOptions{ + resp.Diagnostics.Append(functions.ProviderConfig.As(ctx, &namespace, basetypes.ObjectAsOptions{ UnhandledNullAsEmpty: true, UnhandledUnknownAsEmpty: true, })...) diff --git a/internal/providers/pluginfw/products/cluster/data_cluster.go b/internal/providers/pluginfw/products/cluster/data_cluster.go index 315c3e5024..75ff13106e 100644 --- a/internal/providers/pluginfw/products/cluster/data_cluster.go +++ b/internal/providers/pluginfw/products/cluster/data_cluster.go @@ -35,10 +35,10 @@ type ClusterDataSource struct { } type ClusterInfo struct { - ClusterId types.String `tfsdk:"cluster_id"` - Name types.String `tfsdk:"cluster_name"` - ClusterInfo types.List `tfsdk:"cluster_info"` - ProviderConfigData types.Object `tfsdk:"provider_config"` + ClusterId types.String `tfsdk:"cluster_id"` + Name types.String `tfsdk:"cluster_name"` + ClusterInfo types.List `tfsdk:"cluster_info"` + tfschema.Namespace } func (ClusterInfo) ApplySchemaCustomizations(attrs map[string]tfschema.AttributeBuilder) map[string]tfschema.AttributeBuilder { @@ -84,9 +84,9 @@ func (d *ClusterDataSource) Read(ctx context.Context, req datasource.ReadRequest } var workspaceID string - if !clusterInfo.ProviderConfigData.IsNull() { + if !clusterInfo.ProviderConfig.IsNull() { var namespace tfschema.ProviderConfigData - resp.Diagnostics.Append(clusterInfo.ProviderConfigData.As(ctx, &namespace, basetypes.ObjectAsOptions{ + resp.Diagnostics.Append(clusterInfo.ProviderConfig.As(ctx, &namespace, basetypes.ObjectAsOptions{ UnhandledNullAsEmpty: true, UnhandledUnknownAsEmpty: true, })...) diff --git a/internal/providers/pluginfw/products/dashboards/data_dashboards.go b/internal/providers/pluginfw/products/dashboards/data_dashboards.go index e27a7d25bd..1d115b1c4b 100644 --- a/internal/providers/pluginfw/products/dashboards/data_dashboards.go +++ b/internal/providers/pluginfw/products/dashboards/data_dashboards.go @@ -35,7 +35,7 @@ type DashboardsDataSource struct { type DashboardsInfo struct { DashboardNameContains types.String `tfsdk:"dashboard_name_contains"` Dashboards types.List `tfsdk:"dashboards"` - ProviderConfig types.Object `tfsdk:"provider_config"` + tfschema.Namespace } func (DashboardsInfo) ApplySchemaCustomizations(attrs map[string]tfschema.AttributeBuilder) map[string]tfschema.AttributeBuilder { diff --git a/internal/providers/pluginfw/products/notificationdestinations/data_notification_destinations.go b/internal/providers/pluginfw/products/notificationdestinations/data_notification_destinations.go index 1c4c167db4..9b6d457104 100755 --- a/internal/providers/pluginfw/products/notificationdestinations/data_notification_destinations.go +++ b/internal/providers/pluginfw/products/notificationdestinations/data_notification_destinations.go @@ -38,7 +38,7 @@ type NotificationDestinationsInfo struct { DisplayNameContains types.String `tfsdk:"display_name_contains"` Type types.String `tfsdk:"type"` NotificationDestinations types.List `tfsdk:"notification_destinations"` - ProviderConfigData types.Object `tfsdk:"provider_config"` + tfschema.Namespace } func (NotificationDestinationsInfo) ApplySchemaCustomizations(attrs map[string]tfschema.AttributeBuilder) map[string]tfschema.AttributeBuilder { @@ -103,9 +103,9 @@ func (d *NotificationDestinationsDataSource) Read(ctx context.Context, req datas } var workspaceID string - if !notificationInfo.ProviderConfigData.IsNull() { + if !notificationInfo.ProviderConfig.IsNull() { var namespace tfschema.ProviderConfigData - resp.Diagnostics.Append(notificationInfo.ProviderConfigData.As(ctx, &namespace, basetypes.ObjectAsOptions{ + resp.Diagnostics.Append(notificationInfo.ProviderConfig.As(ctx, &namespace, basetypes.ObjectAsOptions{ UnhandledNullAsEmpty: true, UnhandledUnknownAsEmpty: true, })...) diff --git a/internal/providers/pluginfw/products/registered_model/data_registered_model.go b/internal/providers/pluginfw/products/registered_model/data_registered_model.go index adc1941446..b96da8d21b 100644 --- a/internal/providers/pluginfw/products/registered_model/data_registered_model.go +++ b/internal/providers/pluginfw/products/registered_model/data_registered_model.go @@ -34,11 +34,11 @@ type RegisteredModelDataSource struct { } type RegisteredModelData struct { - FullName types.String `tfsdk:"full_name"` - IncludeAliases types.Bool `tfsdk:"include_aliases"` - IncludeBrowse types.Bool `tfsdk:"include_browse"` - ModelInfo types.List `tfsdk:"model_info"` - ProviderConfigData types.Object `tfsdk:"provider_config"` + FullName types.String `tfsdk:"full_name"` + IncludeAliases types.Bool `tfsdk:"include_aliases"` + IncludeBrowse types.Bool `tfsdk:"include_browse"` + ModelInfo types.List `tfsdk:"model_info"` + tfschema.Namespace } func (RegisteredModelData) ApplySchemaCustomizations(attrs map[string]tfschema.AttributeBuilder) map[string]tfschema.AttributeBuilder { @@ -86,9 +86,9 @@ func (d *RegisteredModelDataSource) Read(ctx context.Context, req datasource.Rea } var workspaceID string - if !registeredModel.ProviderConfigData.IsNull() { + if !registeredModel.ProviderConfig.IsNull() { var namespace tfschema.ProviderConfigData - resp.Diagnostics.Append(registeredModel.ProviderConfigData.As(ctx, &namespace, basetypes.ObjectAsOptions{ + resp.Diagnostics.Append(registeredModel.ProviderConfig.As(ctx, &namespace, basetypes.ObjectAsOptions{ UnhandledNullAsEmpty: true, UnhandledUnknownAsEmpty: true, })...) diff --git a/internal/providers/pluginfw/products/registered_model/data_registered_model_versions.go b/internal/providers/pluginfw/products/registered_model/data_registered_model_versions.go index 7bf90f6aa7..58210beec1 100644 --- a/internal/providers/pluginfw/products/registered_model/data_registered_model_versions.go +++ b/internal/providers/pluginfw/products/registered_model/data_registered_model_versions.go @@ -28,9 +28,9 @@ type RegisteredModelVersionsDataSource struct { } type RegisteredModelVersionsData struct { - FullName types.String `tfsdk:"full_name"` - ModelVersions types.List `tfsdk:"model_versions"` - ProviderConfigData types.Object `tfsdk:"provider_config"` + FullName types.String `tfsdk:"full_name"` + ModelVersions types.List `tfsdk:"model_versions"` + tfschema.Namespace } func (RegisteredModelVersionsData) ApplySchemaCustomizations(attrs map[string]tfschema.AttributeBuilder) map[string]tfschema.AttributeBuilder { @@ -74,9 +74,9 @@ func (d *RegisteredModelVersionsDataSource) Read(ctx context.Context, req dataso } var workspaceID string - if !registeredModelVersions.ProviderConfigData.IsNull() { + if !registeredModelVersions.ProviderConfig.IsNull() { var namespace tfschema.ProviderConfigData - resp.Diagnostics.Append(registeredModelVersions.ProviderConfigData.As(ctx, &namespace, basetypes.ObjectAsOptions{ + resp.Diagnostics.Append(registeredModelVersions.ProviderConfig.As(ctx, &namespace, basetypes.ObjectAsOptions{ UnhandledNullAsEmpty: true, UnhandledUnknownAsEmpty: true, })...) diff --git a/internal/providers/pluginfw/products/serving/data_serving_endpoints.go b/internal/providers/pluginfw/products/serving/data_serving_endpoints.go index df0cd116b4..ff353c938f 100644 --- a/internal/providers/pluginfw/products/serving/data_serving_endpoints.go +++ b/internal/providers/pluginfw/products/serving/data_serving_endpoints.go @@ -28,8 +28,8 @@ type ServingEndpointsDataSource struct { } type ServingEndpointsData struct { - Endpoints types.List `tfsdk:"endpoints"` - ProviderConfigData types.Object `tfsdk:"provider_config"` + Endpoints types.List `tfsdk:"endpoints"` + tfschema.Namespace } func (ServingEndpointsData) ApplySchemaCustomizations(attrs map[string]tfschema.AttributeBuilder) map[string]tfschema.AttributeBuilder { @@ -72,9 +72,9 @@ func (d *ServingEndpointsDataSource) Read(ctx context.Context, req datasource.Re } var workspaceID string - if !endpoints.ProviderConfigData.IsNull() { + if !endpoints.ProviderConfig.IsNull() { var namespace tfschema.ProviderConfigData - resp.Diagnostics.Append(endpoints.ProviderConfigData.As(ctx, &namespace, basetypes.ObjectAsOptions{ + resp.Diagnostics.Append(endpoints.ProviderConfig.As(ctx, &namespace, basetypes.ObjectAsOptions{ UnhandledNullAsEmpty: true, UnhandledUnknownAsEmpty: true, })...) diff --git a/internal/providers/pluginfw/products/volume/data_volumes.go b/internal/providers/pluginfw/products/volume/data_volumes.go index 262e8b80ef..44989a71ed 100644 --- a/internal/providers/pluginfw/products/volume/data_volumes.go +++ b/internal/providers/pluginfw/products/volume/data_volumes.go @@ -32,10 +32,10 @@ type VolumesDataSource struct { } type VolumesList struct { - CatalogName types.String `tfsdk:"catalog_name"` - SchemaName types.String `tfsdk:"schema_name"` - Ids types.List `tfsdk:"ids"` - ProviderConfigData types.Object `tfsdk:"provider_config"` + CatalogName types.String `tfsdk:"catalog_name"` + SchemaName types.String `tfsdk:"schema_name"` + Ids types.List `tfsdk:"ids"` + tfschema.Namespace } func (VolumesList) ApplySchemaCustomizations(attrs map[string]tfschema.AttributeBuilder) map[string]tfschema.AttributeBuilder { @@ -84,9 +84,9 @@ func (d *VolumesDataSource) Read(ctx context.Context, req datasource.ReadRequest converters.TfSdkToGoSdkStruct(ctx, volumesList, &listVolumesRequest) var workspaceID string - if !volumesList.ProviderConfigData.IsNull() { + if !volumesList.ProviderConfig.IsNull() { var namespace tfschema.ProviderConfigData - resp.Diagnostics.Append(volumesList.ProviderConfigData.As(ctx, &namespace, basetypes.ObjectAsOptions{ + resp.Diagnostics.Append(volumesList.ProviderConfig.As(ctx, &namespace, basetypes.ObjectAsOptions{ UnhandledNullAsEmpty: true, UnhandledUnknownAsEmpty: true, })...) From cd15e3650b94de8c7c734c2624067d62a5bf1cf3 Mon Sep 17 00:00:00 2001 From: Tanmay Rustagi Date: Tue, 21 Oct 2025 19:04:03 +0530 Subject: [PATCH 4/8] - --- .../pluginfw/products/sharing/data_share.go | 46 +++++++++++++-- .../pluginfw/products/sharing/data_shares.go | 56 ++++++++++++++----- .../products/sharing/data_shares_acc_test.go | 47 ++++++++++++++++ 3 files changed, 130 insertions(+), 19 deletions(-) diff --git a/internal/providers/pluginfw/products/sharing/data_share.go b/internal/providers/pluginfw/products/sharing/data_share.go index 7395102aaf..bfa4c06327 100644 --- a/internal/providers/pluginfw/products/sharing/data_share.go +++ b/internal/providers/pluginfw/products/sharing/data_share.go @@ -2,6 +2,7 @@ package sharing import ( "context" + "reflect" "github.com/databricks/databricks-sdk-go/apierr" "github.com/databricks/databricks-sdk-go/service/sharing" @@ -13,6 +14,7 @@ import ( "github.com/databricks/terraform-provider-databricks/internal/service/sharing_tf" "github.com/hashicorp/terraform-plugin-framework/datasource" "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) const dataSourceNameShare = "share" @@ -27,12 +29,29 @@ type ShareDataSource struct { Client *common.DatabricksClient } +type ShareData struct { + sharing_tf.ShareInfo + tfschema.Namespace +} + +func (s ShareData) GetComplexFieldTypes(ctx context.Context) map[string]reflect.Type { + types := s.ShareInfo.GetComplexFieldTypes(ctx) + types["provider_config"] = reflect.TypeOf(tfschema.ProviderConfigData{}) + return types +} + +func (s ShareData) ApplySchemaCustomizations(attrs map[string]tfschema.AttributeBuilder) map[string]tfschema.AttributeBuilder { + s.ShareInfo.ApplySchemaCustomizations(attrs) + attrs["provider_config"] = attrs["provider_config"].SetOptional() + return attrs +} + func (d *ShareDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { resp.TypeName = pluginfwcommon.GetDatabricksProductionName(dataSourceNameShare) } func (d *ShareDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { - attrs, blocks := tfschema.DataSourceStructToSchemaMap(ctx, sharing_tf.ShareInfo{}, nil) + attrs, blocks := tfschema.DataSourceStructToSchemaMap(ctx, ShareData{}, nil) resp.Schema = schema.Schema{ Attributes: attrs, Blocks: blocks, @@ -47,14 +66,26 @@ func (d *ShareDataSource) Configure(_ context.Context, req datasource.ConfigureR func (d *ShareDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { ctx = pluginfwcontext.SetUserAgentInDataSourceContext(ctx, dataSourceNameShare) - w, diags := d.Client.GetWorkspaceClient() - resp.Diagnostics.Append(diags...) + + var config ShareData + resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) if resp.Diagnostics.HasError() { return } - var config sharing_tf.ShareInfo - diags = req.Config.Get(ctx, &config) + var workspaceID string + if !config.ProviderConfig.IsNull() { + var namespace tfschema.ProviderConfigData + resp.Diagnostics.Append(config.ProviderConfig.As(ctx, &namespace, basetypes.ObjectAsOptions{ + UnhandledNullAsEmpty: true, + UnhandledUnknownAsEmpty: true, + })...) + if resp.Diagnostics.HasError() { + return + } + workspaceID = namespace.WorkspaceID.ValueString() + } + w, diags := d.Client.GetWorkspaceClientForUnifiedProviderWithDiagnostics(ctx, workspaceID) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { return @@ -73,11 +104,14 @@ func (d *ShareDataSource) Read(ctx context.Context, req datasource.ReadRequest, return } - var shareInfoTfSdk sharing_tf.ShareInfo + var shareInfoTfSdk ShareData resp.Diagnostics.Append(converters.GoSdkToTfSdkStruct(ctx, share, &shareInfoTfSdk)...) if resp.Diagnostics.HasError() { return } + shareInfoTfSdk.Namespace = tfschema.Namespace{ + ProviderConfig: config.ProviderConfig, + } resp.Diagnostics.Append(resp.State.Set(ctx, shareInfoTfSdk)...) } diff --git a/internal/providers/pluginfw/products/sharing/data_shares.go b/internal/providers/pluginfw/products/sharing/data_shares.go index 01fa3b2157..3cd1459507 100644 --- a/internal/providers/pluginfw/products/sharing/data_shares.go +++ b/internal/providers/pluginfw/products/sharing/data_shares.go @@ -13,34 +13,38 @@ import ( "github.com/hashicorp/terraform-plugin-framework/datasource" "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) const dataSourceNameShares = "shares" type SharesList struct { Shares types.List `tfsdk:"shares"` + tfschema.Namespace } -func (SharesList) ApplySchemaCustomizations(attrs map[string]tfschema.AttributeBuilder) map[string]tfschema.AttributeBuilder { - attrs["shares"] = attrs["shares"].SetComputed().SetOptional() - - return attrs -} - -func (SharesList) GetComplexFieldTypes(context.Context) map[string]reflect.Type { +func (s SharesList) GetComplexFieldTypes(context.Context) map[string]reflect.Type { return map[string]reflect.Type{ - "shares": reflect.TypeOf(types.String{}), + "shares": reflect.TypeOf(types.String{}), + "provider_config": reflect.TypeOf(tfschema.ProviderConfigData{}), } } -func (SharesList) ToObjectType(ctx context.Context) types.ObjectType { +func (s SharesList) ToObjectType(ctx context.Context) types.ObjectType { return types.ObjectType{ AttrTypes: map[string]attr.Type{ - "shares": types.ListType{ElemType: types.StringType}, + "shares": types.ListType{ElemType: types.StringType}, + "provider_config": tfschema.ProviderConfigData{}.Type(ctx), }, } } +func (s SharesList) ApplySchemaCustomizations(attrs map[string]tfschema.AttributeBuilder) map[string]tfschema.AttributeBuilder { + attrs["shares"] = attrs["shares"].SetComputed().SetOptional() + attrs["provider_config"] = attrs["provider_config"].SetOptional() + return attrs +} + func DataSourceShares() datasource.DataSource { return &SharesDataSource{} } @@ -71,8 +75,28 @@ func (d *SharesDataSource) Configure(_ context.Context, req datasource.Configure func (d *SharesDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { ctx = pluginfwcontext.SetUserAgentInDataSourceContext(ctx, dataSourceNameShares) - w, diags := d.Client.GetWorkspaceClient() - resp.Diagnostics.Append(diags...) + + var config SharesList + resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) + if resp.Diagnostics.HasError() { + return + } + + var workspaceID string + if !config.ProviderConfig.IsNull() { + var namespace tfschema.ProviderConfigData + resp.Diagnostics.Append(config.ProviderConfig.As(ctx, &namespace, basetypes.ObjectAsOptions{ + UnhandledNullAsEmpty: true, + UnhandledUnknownAsEmpty: true, + })...) + if resp.Diagnostics.HasError() { + return + } + workspaceID = namespace.WorkspaceID.ValueString() + } + w, clientDiags := d.Client.GetWorkspaceClientForUnifiedProviderWithDiagnostics(ctx, workspaceID) + + resp.Diagnostics.Append(clientDiags...) if resp.Diagnostics.HasError() { return } @@ -88,5 +112,11 @@ func (d *SharesDataSource) Read(ctx context.Context, req datasource.ReadRequest, shareNames[i] = types.StringValue(share.Name) } - resp.Diagnostics.Append(resp.State.Set(ctx, SharesList{Shares: types.ListValueMust(types.StringType, shareNames)})...) + newState := SharesList{ + Shares: types.ListValueMust(types.StringType, shareNames), + Namespace: tfschema.Namespace{ + ProviderConfig: config.ProviderConfig, + }, + } + resp.Diagnostics.Append(resp.State.Set(ctx, newState)...) } diff --git a/internal/providers/pluginfw/products/sharing/data_shares_acc_test.go b/internal/providers/pluginfw/products/sharing/data_shares_acc_test.go index c6237f0095..928ca8d0c6 100644 --- a/internal/providers/pluginfw/products/sharing/data_shares_acc_test.go +++ b/internal/providers/pluginfw/products/sharing/data_shares_acc_test.go @@ -1,6 +1,8 @@ package sharing_test import ( + "fmt" + "regexp" "strconv" "testing" @@ -88,3 +90,48 @@ func TestUcAccDataSourceShares(t *testing.T) { Check: checkSharesDataSourcePopulated(t), }) } + +func dataSourceSharesTemplate(provider_config string) string { + return fmt.Sprintf(` + resource "databricks_share" "myshare" { + name = "{var.STICKY_RANDOM}-share-config" + object { + name = databricks_schema.schema1.id + data_object_type = "SCHEMA" + } + } + data "databricks_shares" "this" { + %s + depends_on = [databricks_share.myshare] + } +`, provider_config) +} + +func TestAccShare_ProviderConfig_Invalid(t *testing.T) { + acceptance.UnityWorkspaceLevel(t, acceptance.Step{ + Template: preTestTemplateSchema + dataSourceSharesTemplate(` + provider_config = { + workspace_id = "invalid" + } + `), + ExpectError: regexp.MustCompile( + `Attribute provider_config\.workspace_id\s+workspace_id must be a valid integer`, + ), + PlanOnly: true, + }) +} + +func TestAccShare_ProviderConfig_Mismatched(t *testing.T) { + acceptance.UnityWorkspaceLevel(t, acceptance.Step{ + Template: preTestTemplateSchema + dataSourceSharesTemplate(` + provider_config = { + workspace_id = "123" + } + `), + ExpectError: regexp.MustCompile( + `(?s)failed to get workspace client.*workspace_id mismatch` + + `.*please check the workspace_id provided in ` + + `provider_config`, + ), + }) +} From f88bf839388e864adbc9694397e534e6fb6af516 Mon Sep 17 00:00:00 2001 From: Tanmay Rustagi Date: Thu, 23 Oct 2025 03:55:54 +0530 Subject: [PATCH 5/8] - --- .../pluginfw/products/app/data_app.go | 16 +- .../pluginfw/products/app/data_apps.go | 16 +- .../pluginfw/products/app/resource_app.go | 61 ++----- .../products/catalog/data_functions.go | 16 +- .../pluginfw/products/cluster/data_cluster.go | 16 +- .../products/dashboards/data_dashboards.go | 18 +-- .../data_notification_destinations.go | 16 +- .../registered_model/data_registered_model.go | 15 +- .../data_registered_model_versions.go | 16 +- .../serving/data_serving_endpoints.go | 16 +- .../pluginfw/products/sharing/data_share.go | 17 +- .../pluginfw/products/sharing/data_shares.go | 17 +- .../pluginfw/products/volume/data_volumes.go | 17 +- .../pluginfw/tfschema/unified_provider.go | 45 ++++++ .../tfschema/unified_provider_test.go | 150 ++++++++++++++++++ 15 files changed, 264 insertions(+), 188 deletions(-) diff --git a/internal/providers/pluginfw/products/app/data_app.go b/internal/providers/pluginfw/products/app/data_app.go index d0a7095a17..28bf2cc05b 100644 --- a/internal/providers/pluginfw/products/app/data_app.go +++ b/internal/providers/pluginfw/products/app/data_app.go @@ -12,7 +12,6 @@ import ( "github.com/databricks/terraform-provider-databricks/internal/service/apps_tf" "github.com/hashicorp/terraform-plugin-framework/datasource" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) func DataSourceApp() datasource.DataSource { @@ -68,17 +67,10 @@ func (a *dataSourceApp) Read(ctx context.Context, req datasource.ReadRequest, re return } - var workspaceID string - if !config.ProviderConfig.IsNull() { - var namespace tfschema.ProviderConfigData - resp.Diagnostics.Append(config.ProviderConfig.As(ctx, &namespace, basetypes.ObjectAsOptions{ - UnhandledNullAsEmpty: true, - UnhandledUnknownAsEmpty: true, - })...) - if resp.Diagnostics.HasError() { - return - } - workspaceID = namespace.WorkspaceID.ValueString() + workspaceID, diags := tfschema.GetWorkspaceIDDataSource(ctx, config.ProviderConfig) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return } w, diags := a.client.GetWorkspaceClientForUnifiedProviderWithDiagnostics(ctx, workspaceID) diff --git a/internal/providers/pluginfw/products/app/data_apps.go b/internal/providers/pluginfw/products/app/data_apps.go index b174a114c5..07210b013f 100644 --- a/internal/providers/pluginfw/products/app/data_apps.go +++ b/internal/providers/pluginfw/products/app/data_apps.go @@ -14,7 +14,6 @@ import ( "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/datasource" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) func DataSourceApps() datasource.DataSource { @@ -68,17 +67,10 @@ func (a *dataSourceApps) Read(ctx context.Context, req datasource.ReadRequest, r return } - var workspaceID string - if !config.ProviderConfig.IsNull() { - var namespace tfschema.ProviderConfigData - resp.Diagnostics.Append(config.ProviderConfig.As(ctx, &namespace, basetypes.ObjectAsOptions{ - UnhandledNullAsEmpty: true, - UnhandledUnknownAsEmpty: true, - })...) - if resp.Diagnostics.HasError() { - return - } - workspaceID = namespace.WorkspaceID.ValueString() + workspaceID, diags := tfschema.GetWorkspaceIDDataSource(ctx, config.ProviderConfig) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return } w, diags := a.client.GetWorkspaceClientForUnifiedProviderWithDiagnostics(ctx, workspaceID) diff --git a/internal/providers/pluginfw/products/app/resource_app.go b/internal/providers/pluginfw/products/app/resource_app.go index bcdebb792c..113f5e478b 100644 --- a/internal/providers/pluginfw/products/app/resource_app.go +++ b/internal/providers/pluginfw/products/app/resource_app.go @@ -22,7 +22,6 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64planmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) const ( @@ -110,17 +109,10 @@ func (a *resourceApp) Create(ctx context.Context, req resource.CreateRequest, re return } - var workspaceID string - if !app.ProviderConfig.IsNull() { - var namespace tfschema.ProviderConfigData - resp.Diagnostics.Append(app.ProviderConfig.As(ctx, &namespace, basetypes.ObjectAsOptions{ - UnhandledNullAsEmpty: true, - UnhandledUnknownAsEmpty: true, - })...) - if resp.Diagnostics.HasError() { - return - } - workspaceID = namespace.WorkspaceID.ValueString() + workspaceID, diags := tfschema.GetWorkspaceIDResource(ctx, app.ProviderConfig) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return } w, diags := a.client.GetWorkspaceClientForUnifiedProviderWithDiagnostics(ctx, workspaceID) @@ -228,17 +220,10 @@ func (a *resourceApp) Read(ctx context.Context, req resource.ReadRequest, resp * return } - var workspaceID string - if !app.ProviderConfig.IsNull() { - var namespace tfschema.ProviderConfigData - resp.Diagnostics.Append(app.ProviderConfig.As(ctx, &namespace, basetypes.ObjectAsOptions{ - UnhandledNullAsEmpty: true, - UnhandledUnknownAsEmpty: true, - })...) - if resp.Diagnostics.HasError() { - return - } - workspaceID = namespace.WorkspaceID.ValueString() + workspaceID, diags := tfschema.GetWorkspaceIDResource(ctx, app.ProviderConfig) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return } w, diags := a.client.GetWorkspaceClientForUnifiedProviderWithDiagnostics(ctx, workspaceID) @@ -275,17 +260,10 @@ func (a *resourceApp) Update(ctx context.Context, req resource.UpdateRequest, re return } - var workspaceID string - if !app.ProviderConfig.IsNull() { - var namespace tfschema.ProviderConfigData - resp.Diagnostics.Append(app.ProviderConfig.As(ctx, &namespace, basetypes.ObjectAsOptions{ - UnhandledNullAsEmpty: true, - UnhandledUnknownAsEmpty: true, - })...) - if resp.Diagnostics.HasError() { - return - } - workspaceID = namespace.WorkspaceID.ValueString() + workspaceID, diags := tfschema.GetWorkspaceIDResource(ctx, app.ProviderConfig) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return } w, diags := a.client.GetWorkspaceClientForUnifiedProviderWithDiagnostics(ctx, workspaceID) @@ -330,17 +308,10 @@ func (a *resourceApp) Delete(ctx context.Context, req resource.DeleteRequest, re return } - var workspaceID string - if !app.ProviderConfig.IsNull() { - var namespace tfschema.ProviderConfigData - resp.Diagnostics.Append(app.ProviderConfig.As(ctx, &namespace, basetypes.ObjectAsOptions{ - UnhandledNullAsEmpty: true, - UnhandledUnknownAsEmpty: true, - })...) - if resp.Diagnostics.HasError() { - return - } - workspaceID = namespace.WorkspaceID.ValueString() + workspaceID, diags := tfschema.GetWorkspaceIDResource(ctx, app.ProviderConfig) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return } w, diags := a.client.GetWorkspaceClientForUnifiedProviderWithDiagnostics(ctx, workspaceID) diff --git a/internal/providers/pluginfw/products/catalog/data_functions.go b/internal/providers/pluginfw/products/catalog/data_functions.go index ce6164183c..e25f7ba407 100644 --- a/internal/providers/pluginfw/products/catalog/data_functions.go +++ b/internal/providers/pluginfw/products/catalog/data_functions.go @@ -17,7 +17,6 @@ import ( "github.com/hashicorp/terraform-plugin-framework/datasource" "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) const dataSourceName = "functions" @@ -84,17 +83,10 @@ func (d *FunctionsDataSource) Read(ctx context.Context, req datasource.ReadReque return } - var workspaceID string - if !functions.ProviderConfig.IsNull() { - var namespace tfschema.ProviderConfigData - resp.Diagnostics.Append(functions.ProviderConfig.As(ctx, &namespace, basetypes.ObjectAsOptions{ - UnhandledNullAsEmpty: true, - UnhandledUnknownAsEmpty: true, - })...) - if resp.Diagnostics.HasError() { - return - } - workspaceID = namespace.WorkspaceID.ValueString() + workspaceID, diags := tfschema.GetWorkspaceIDDataSource(ctx, functions.ProviderConfig) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return } w, diags := d.Client.GetWorkspaceClientForUnifiedProviderWithDiagnostics(ctx, workspaceID) diff --git a/internal/providers/pluginfw/products/cluster/data_cluster.go b/internal/providers/pluginfw/products/cluster/data_cluster.go index 75ff13106e..baa397da5a 100644 --- a/internal/providers/pluginfw/products/cluster/data_cluster.go +++ b/internal/providers/pluginfw/products/cluster/data_cluster.go @@ -19,7 +19,6 @@ import ( "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) const dataSourceName = "cluster" @@ -83,17 +82,10 @@ func (d *ClusterDataSource) Read(ctx context.Context, req datasource.ReadRequest return } - var workspaceID string - if !clusterInfo.ProviderConfig.IsNull() { - var namespace tfschema.ProviderConfigData - resp.Diagnostics.Append(clusterInfo.ProviderConfig.As(ctx, &namespace, basetypes.ObjectAsOptions{ - UnhandledNullAsEmpty: true, - UnhandledUnknownAsEmpty: true, - })...) - if resp.Diagnostics.HasError() { - return - } - workspaceID = namespace.WorkspaceID.ValueString() + workspaceID, diags := tfschema.GetWorkspaceIDDataSource(ctx, clusterInfo.ProviderConfig) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return } w, diags := d.Client.GetWorkspaceClientForUnifiedProviderWithDiagnostics(ctx, workspaceID) diff --git a/internal/providers/pluginfw/products/dashboards/data_dashboards.go b/internal/providers/pluginfw/products/dashboards/data_dashboards.go index 1d115b1c4b..7f650bf191 100644 --- a/internal/providers/pluginfw/products/dashboards/data_dashboards.go +++ b/internal/providers/pluginfw/products/dashboards/data_dashboards.go @@ -17,7 +17,6 @@ import ( "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) const dataSourceName = "dashboards" @@ -82,18 +81,13 @@ func (d *DashboardsDataSource) Read(ctx context.Context, req datasource.ReadRequ if AppendDiagAndCheckErrors(resp, req.Config.Get(ctx, &dashboardInfo)) { return } - var workspaceID string - if !dashboardInfo.ProviderConfig.IsNull() { - var namespace tfschema.ProviderConfigData - resp.Diagnostics.Append(dashboardInfo.ProviderConfig.As(ctx, &namespace, basetypes.ObjectAsOptions{ - UnhandledNullAsEmpty: true, - UnhandledUnknownAsEmpty: true, - })...) - if resp.Diagnostics.HasError() { - return - } - workspaceID = namespace.WorkspaceID.ValueString() + + workspaceID, diags := tfschema.GetWorkspaceIDDataSource(ctx, dashboardInfo.ProviderConfig) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return } + w, diags := d.Client.GetWorkspaceClientForUnifiedProviderWithDiagnostics(ctx, workspaceID) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { diff --git a/internal/providers/pluginfw/products/notificationdestinations/data_notification_destinations.go b/internal/providers/pluginfw/products/notificationdestinations/data_notification_destinations.go index 9b6d457104..17283fc93d 100755 --- a/internal/providers/pluginfw/products/notificationdestinations/data_notification_destinations.go +++ b/internal/providers/pluginfw/products/notificationdestinations/data_notification_destinations.go @@ -19,7 +19,6 @@ import ( "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) const dataSourceName = "notification_destinations" @@ -102,17 +101,10 @@ func (d *NotificationDestinationsDataSource) Read(ctx context.Context, req datas return } - var workspaceID string - if !notificationInfo.ProviderConfig.IsNull() { - var namespace tfschema.ProviderConfigData - resp.Diagnostics.Append(notificationInfo.ProviderConfig.As(ctx, &namespace, basetypes.ObjectAsOptions{ - UnhandledNullAsEmpty: true, - UnhandledUnknownAsEmpty: true, - })...) - if resp.Diagnostics.HasError() { - return - } - workspaceID = namespace.WorkspaceID.ValueString() + workspaceID, diags := tfschema.GetWorkspaceIDDataSource(ctx, notificationInfo.ProviderConfig) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return } w, diags := d.Client.GetWorkspaceClientForUnifiedProviderWithDiagnostics(ctx, workspaceID) diff --git a/internal/providers/pluginfw/products/registered_model/data_registered_model.go b/internal/providers/pluginfw/products/registered_model/data_registered_model.go index b96da8d21b..08b71a16a1 100644 --- a/internal/providers/pluginfw/products/registered_model/data_registered_model.go +++ b/internal/providers/pluginfw/products/registered_model/data_registered_model.go @@ -85,17 +85,10 @@ func (d *RegisteredModelDataSource) Read(ctx context.Context, req datasource.Rea return } - var workspaceID string - if !registeredModel.ProviderConfig.IsNull() { - var namespace tfschema.ProviderConfigData - resp.Diagnostics.Append(registeredModel.ProviderConfig.As(ctx, &namespace, basetypes.ObjectAsOptions{ - UnhandledNullAsEmpty: true, - UnhandledUnknownAsEmpty: true, - })...) - if resp.Diagnostics.HasError() { - return - } - workspaceID = namespace.WorkspaceID.ValueString() + workspaceID, diags := tfschema.GetWorkspaceIDDataSource(ctx, registeredModel.ProviderConfig) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return } w, diags := d.Client.GetWorkspaceClientForUnifiedProviderWithDiagnostics(ctx, workspaceID) diff --git a/internal/providers/pluginfw/products/registered_model/data_registered_model_versions.go b/internal/providers/pluginfw/products/registered_model/data_registered_model_versions.go index 58210beec1..aba6c29666 100644 --- a/internal/providers/pluginfw/products/registered_model/data_registered_model_versions.go +++ b/internal/providers/pluginfw/products/registered_model/data_registered_model_versions.go @@ -14,7 +14,6 @@ import ( "github.com/hashicorp/terraform-plugin-framework/datasource" "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) func DataSourceRegisteredModelVersions() datasource.DataSource { @@ -73,17 +72,10 @@ func (d *RegisteredModelVersionsDataSource) Read(ctx context.Context, req dataso return } - var workspaceID string - if !registeredModelVersions.ProviderConfig.IsNull() { - var namespace tfschema.ProviderConfigData - resp.Diagnostics.Append(registeredModelVersions.ProviderConfig.As(ctx, &namespace, basetypes.ObjectAsOptions{ - UnhandledNullAsEmpty: true, - UnhandledUnknownAsEmpty: true, - })...) - if resp.Diagnostics.HasError() { - return - } - workspaceID = namespace.WorkspaceID.ValueString() + workspaceID, diags := tfschema.GetWorkspaceIDDataSource(ctx, registeredModelVersions.ProviderConfig) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return } w, diags := d.Client.GetWorkspaceClientForUnifiedProviderWithDiagnostics(ctx, workspaceID) diff --git a/internal/providers/pluginfw/products/serving/data_serving_endpoints.go b/internal/providers/pluginfw/products/serving/data_serving_endpoints.go index ff353c938f..f1cef2589d 100644 --- a/internal/providers/pluginfw/products/serving/data_serving_endpoints.go +++ b/internal/providers/pluginfw/products/serving/data_serving_endpoints.go @@ -14,7 +14,6 @@ import ( "github.com/hashicorp/terraform-plugin-framework/datasource" "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) func DataSourceServingEndpoints() datasource.DataSource { @@ -71,17 +70,10 @@ func (d *ServingEndpointsDataSource) Read(ctx context.Context, req datasource.Re return } - var workspaceID string - if !endpoints.ProviderConfig.IsNull() { - var namespace tfschema.ProviderConfigData - resp.Diagnostics.Append(endpoints.ProviderConfig.As(ctx, &namespace, basetypes.ObjectAsOptions{ - UnhandledNullAsEmpty: true, - UnhandledUnknownAsEmpty: true, - })...) - if resp.Diagnostics.HasError() { - return - } - workspaceID = namespace.WorkspaceID.ValueString() + workspaceID, diags := tfschema.GetWorkspaceIDDataSource(ctx, endpoints.ProviderConfig) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return } w, diags := d.Client.GetWorkspaceClientForUnifiedProviderWithDiagnostics(ctx, workspaceID) diff --git a/internal/providers/pluginfw/products/sharing/data_share.go b/internal/providers/pluginfw/products/sharing/data_share.go index bfa4c06327..4a62ebca8c 100644 --- a/internal/providers/pluginfw/products/sharing/data_share.go +++ b/internal/providers/pluginfw/products/sharing/data_share.go @@ -14,7 +14,6 @@ import ( "github.com/databricks/terraform-provider-databricks/internal/service/sharing_tf" "github.com/hashicorp/terraform-plugin-framework/datasource" "github.com/hashicorp/terraform-plugin-framework/datasource/schema" - "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) const dataSourceNameShare = "share" @@ -73,18 +72,12 @@ func (d *ShareDataSource) Read(ctx context.Context, req datasource.ReadRequest, return } - var workspaceID string - if !config.ProviderConfig.IsNull() { - var namespace tfschema.ProviderConfigData - resp.Diagnostics.Append(config.ProviderConfig.As(ctx, &namespace, basetypes.ObjectAsOptions{ - UnhandledNullAsEmpty: true, - UnhandledUnknownAsEmpty: true, - })...) - if resp.Diagnostics.HasError() { - return - } - workspaceID = namespace.WorkspaceID.ValueString() + workspaceID, diags := tfschema.GetWorkspaceIDDataSource(ctx, config.ProviderConfig) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return } + w, diags := d.Client.GetWorkspaceClientForUnifiedProviderWithDiagnostics(ctx, workspaceID) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { diff --git a/internal/providers/pluginfw/products/sharing/data_shares.go b/internal/providers/pluginfw/products/sharing/data_shares.go index 3cd1459507..39822cf478 100644 --- a/internal/providers/pluginfw/products/sharing/data_shares.go +++ b/internal/providers/pluginfw/products/sharing/data_shares.go @@ -13,7 +13,6 @@ import ( "github.com/hashicorp/terraform-plugin-framework/datasource" "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) const dataSourceNameShares = "shares" @@ -82,18 +81,12 @@ func (d *SharesDataSource) Read(ctx context.Context, req datasource.ReadRequest, return } - var workspaceID string - if !config.ProviderConfig.IsNull() { - var namespace tfschema.ProviderConfigData - resp.Diagnostics.Append(config.ProviderConfig.As(ctx, &namespace, basetypes.ObjectAsOptions{ - UnhandledNullAsEmpty: true, - UnhandledUnknownAsEmpty: true, - })...) - if resp.Diagnostics.HasError() { - return - } - workspaceID = namespace.WorkspaceID.ValueString() + workspaceID, diags := tfschema.GetWorkspaceIDDataSource(ctx, config.ProviderConfig) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return } + w, clientDiags := d.Client.GetWorkspaceClientForUnifiedProviderWithDiagnostics(ctx, workspaceID) resp.Diagnostics.Append(clientDiags...) diff --git a/internal/providers/pluginfw/products/volume/data_volumes.go b/internal/providers/pluginfw/products/volume/data_volumes.go index 44989a71ed..593d1cee21 100644 --- a/internal/providers/pluginfw/products/volume/data_volumes.go +++ b/internal/providers/pluginfw/products/volume/data_volumes.go @@ -16,7 +16,6 @@ import ( "github.com/hashicorp/terraform-plugin-framework/datasource" "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) const dataSourceName = "volumes" @@ -83,18 +82,12 @@ func (d *VolumesDataSource) Read(ctx context.Context, req datasource.ReadRequest var listVolumesRequest catalog.ListVolumesRequest converters.TfSdkToGoSdkStruct(ctx, volumesList, &listVolumesRequest) - var workspaceID string - if !volumesList.ProviderConfig.IsNull() { - var namespace tfschema.ProviderConfigData - resp.Diagnostics.Append(volumesList.ProviderConfig.As(ctx, &namespace, basetypes.ObjectAsOptions{ - UnhandledNullAsEmpty: true, - UnhandledUnknownAsEmpty: true, - })...) - if resp.Diagnostics.HasError() { - return - } - workspaceID = namespace.WorkspaceID.ValueString() + workspaceID, diags := tfschema.GetWorkspaceIDDataSource(ctx, volumesList.ProviderConfig) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return } + w, clientDiags := d.Client.GetWorkspaceClientForUnifiedProviderWithDiagnostics(ctx, workspaceID) resp.Diagnostics.Append(clientDiags...) if resp.Diagnostics.HasError() { diff --git a/internal/providers/pluginfw/tfschema/unified_provider.go b/internal/providers/pluginfw/tfschema/unified_provider.go index 6055cd11f4..d79b3eec8a 100644 --- a/internal/providers/pluginfw/tfschema/unified_provider.go +++ b/internal/providers/pluginfw/tfschema/unified_provider.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/types" @@ -116,3 +117,47 @@ func (r ProviderConfigData) Type(ctx context.Context) attr.Type { }, } } + +func GetWorkspaceIDResource(ctx context.Context, providerConfig types.Object) (string, diag.Diagnostics) { + var diags diag.Diagnostics + var workspaceID string + + if providerConfig.IsNull() { + return workspaceID, diags + } + + var namespace ProviderConfig + diags.Append(providerConfig.As(ctx, &namespace, basetypes.ObjectAsOptions{ + UnhandledNullAsEmpty: true, + UnhandledUnknownAsEmpty: true, + })...) + if diags.HasError() { + return workspaceID, diags + } + + workspaceID = namespace.WorkspaceID.ValueString() + + return workspaceID, diags +} + +func GetWorkspaceIDDataSource(ctx context.Context, providerConfig types.Object) (string, diag.Diagnostics) { + var diags diag.Diagnostics + var workspaceID string + + if providerConfig.IsNull() { + return workspaceID, diags + } + + var namespace ProviderConfigData + diags.Append(providerConfig.As(ctx, &namespace, basetypes.ObjectAsOptions{ + UnhandledNullAsEmpty: true, + UnhandledUnknownAsEmpty: true, + })...) + if diags.HasError() { + return workspaceID, diags + } + + workspaceID = namespace.WorkspaceID.ValueString() + + return workspaceID, diags +} diff --git a/internal/providers/pluginfw/tfschema/unified_provider_test.go b/internal/providers/pluginfw/tfschema/unified_provider_test.go index 3ab1b54da1..0b405d1107 100644 --- a/internal/providers/pluginfw/tfschema/unified_provider_test.go +++ b/internal/providers/pluginfw/tfschema/unified_provider_test.go @@ -65,3 +65,153 @@ func TestWorkspaceIDPlanModifier(t *testing.T) { }) } } + +func TestGetWorkspaceIDResource(t *testing.T) { + ctx := context.Background() + + tests := []struct { + name string + setupProviderConfig func() types.Object + expectedWorkspaceID string + expectError bool + }{ + { + name: "valid workspace ID", + setupProviderConfig: func() types.Object { + providerConfig := ProviderConfig{ + WorkspaceID: types.StringValue("123456789"), + } + return providerConfig.ToObjectValue(ctx) + }, + expectedWorkspaceID: "123456789", + expectError: false, + }, + { + name: "null provider_config", + setupProviderConfig: func() types.Object { + return types.ObjectNull(ProviderConfig{}.Type(ctx).(types.ObjectType).AttrTypes) + }, + expectedWorkspaceID: "", + expectError: false, + }, + { + name: "unknown provider_config", + setupProviderConfig: func() types.Object { + return types.ObjectUnknown(ProviderConfig{}.Type(ctx).(types.ObjectType).AttrTypes) + }, + expectedWorkspaceID: "", + expectError: false, + }, + { + name: "empty workspace ID string", + setupProviderConfig: func() types.Object { + providerConfig := ProviderConfig{ + WorkspaceID: types.StringValue(""), + } + return providerConfig.ToObjectValue(ctx) + }, + expectedWorkspaceID: "", + expectError: false, + }, + { + name: "null workspace ID in object", + setupProviderConfig: func() types.Object { + providerConfig := ProviderConfig{ + WorkspaceID: types.StringNull(), + } + return providerConfig.ToObjectValue(ctx) + }, + expectedWorkspaceID: "", + expectError: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + providerConfigObject := tt.setupProviderConfig() + workspaceID, diags := GetWorkspaceIDResource(ctx, providerConfigObject) + + if tt.expectError { + assert.True(t, diags.HasError(), "Expected diagnostics error") + } else { + assert.False(t, diags.HasError(), "Expected no diagnostics error") + } + assert.Equal(t, tt.expectedWorkspaceID, workspaceID, "Workspace ID mismatch") + }) + } +} + +func TestGetWorkspaceIDDataSource(t *testing.T) { + ctx := context.Background() + + tests := []struct { + name string + setupProviderConfig func() types.Object + expectedWorkspaceID string + expectError bool + }{ + { + name: "valid workspace ID", + setupProviderConfig: func() types.Object { + providerConfig := ProviderConfigData{ + WorkspaceID: types.StringValue("123456789"), + } + return providerConfig.ToObjectValue(ctx) + }, + expectedWorkspaceID: "123456789", + expectError: false, + }, + { + name: "null provider_config", + setupProviderConfig: func() types.Object { + return types.ObjectNull(ProviderConfigData{}.Type(ctx).(types.ObjectType).AttrTypes) + }, + expectedWorkspaceID: "", + expectError: false, + }, + { + name: "unknown provider_config", + setupProviderConfig: func() types.Object { + return types.ObjectUnknown(ProviderConfigData{}.Type(ctx).(types.ObjectType).AttrTypes) + }, + expectedWorkspaceID: "", + expectError: false, + }, + { + name: "empty workspace ID string", + setupProviderConfig: func() types.Object { + providerConfig := ProviderConfigData{ + WorkspaceID: types.StringValue(""), + } + return providerConfig.ToObjectValue(ctx) + }, + expectedWorkspaceID: "", + expectError: false, + }, + { + name: "null workspace ID in object", + setupProviderConfig: func() types.Object { + providerConfig := ProviderConfigData{ + WorkspaceID: types.StringNull(), + } + return providerConfig.ToObjectValue(ctx) + }, + expectedWorkspaceID: "", + expectError: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + providerConfigObject := tt.setupProviderConfig() + workspaceID, diags := GetWorkspaceIDDataSource(ctx, providerConfigObject) + + if tt.expectError { + assert.True(t, diags.HasError(), "Expected diagnostics error") + } else { + assert.False(t, diags.HasError(), "Expected no diagnostics error") + } + assert.Equal(t, tt.expectedWorkspaceID, workspaceID, "Workspace ID mismatch") + }) + } +} From 7cf7346843619734108314ec758e909781cc2156 Mon Sep 17 00:00:00 2001 From: Tanmay Rustagi Date: Fri, 24 Oct 2025 02:26:42 +0530 Subject: [PATCH 6/8] - --- .../pluginfw/products/sharing/data_shares_acc_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/providers/pluginfw/products/sharing/data_shares_acc_test.go b/internal/providers/pluginfw/products/sharing/data_shares_acc_test.go index 928ca8d0c6..01b726c082 100644 --- a/internal/providers/pluginfw/products/sharing/data_shares_acc_test.go +++ b/internal/providers/pluginfw/products/sharing/data_shares_acc_test.go @@ -107,7 +107,7 @@ func dataSourceSharesTemplate(provider_config string) string { `, provider_config) } -func TestAccShare_ProviderConfig_Invalid(t *testing.T) { +func TestAccSharesData_ProviderConfig_Invalid(t *testing.T) { acceptance.UnityWorkspaceLevel(t, acceptance.Step{ Template: preTestTemplateSchema + dataSourceSharesTemplate(` provider_config = { @@ -121,7 +121,7 @@ func TestAccShare_ProviderConfig_Invalid(t *testing.T) { }) } -func TestAccShare_ProviderConfig_Mismatched(t *testing.T) { +func TestAccSharesData_ProviderConfig_Mismatched(t *testing.T) { acceptance.UnityWorkspaceLevel(t, acceptance.Step{ Template: preTestTemplateSchema + dataSourceSharesTemplate(` provider_config = { From eb480f979faa52d31985de902e178539004289e9 Mon Sep 17 00:00:00 2001 From: Tanmay Rustagi Date: Fri, 24 Oct 2025 02:38:37 +0530 Subject: [PATCH 7/8] - --- .../pluginfw/tfschema/unified_provider.go | 6 ++++ .../tfschema/unified_provider_test.go | 30 +++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/internal/providers/pluginfw/tfschema/unified_provider.go b/internal/providers/pluginfw/tfschema/unified_provider.go index 84f0a1115a..dda83c496b 100644 --- a/internal/providers/pluginfw/tfschema/unified_provider.go +++ b/internal/providers/pluginfw/tfschema/unified_provider.go @@ -142,6 +142,9 @@ func GetWorkspaceID_SdkV2(ctx context.Context, providerConfig types.List) (strin return workspaceID, diags } +// GetWorkspaceIDResource extracts the workspace ID from a provider_config object (for resources). +// It returns the workspace ID string and any diagnostics encountered during extraction. +// If the provider_config is not set, it returns an empty string with no diagnostics. func GetWorkspaceIDResource(ctx context.Context, providerConfig types.Object) (string, diag.Diagnostics) { var diags diag.Diagnostics var workspaceID string @@ -164,6 +167,9 @@ func GetWorkspaceIDResource(ctx context.Context, providerConfig types.Object) (s return workspaceID, diags } +// GetWorkspaceIDDataSource extracts the workspace ID from a provider_config object (for data sources). +// It returns the workspace ID string and any diagnostics encountered during extraction. +// If the provider_config is not set, it returns an empty string with no diagnostics. func GetWorkspaceIDDataSource(ctx context.Context, providerConfig types.Object) (string, diag.Diagnostics) { var diags diag.Diagnostics var workspaceID string diff --git a/internal/providers/pluginfw/tfschema/unified_provider_test.go b/internal/providers/pluginfw/tfschema/unified_provider_test.go index 5b2b2e4ce4..7510c5d470 100644 --- a/internal/providers/pluginfw/tfschema/unified_provider_test.go +++ b/internal/providers/pluginfw/tfschema/unified_provider_test.go @@ -192,6 +192,21 @@ func TestGetWorkspaceIDResource(t *testing.T) { expectedWorkspaceID: "", expectError: false, }, + { + name: "incompatible object structure", + setupProviderConfig: func() types.Object { + // Create an object with wrong attribute types to trigger conversion error + attrTypes := map[string]attr.Type{ + "workspace_id": types.Int64Type, + } + attrValues := map[string]attr.Value{ + "workspace_id": types.Int64Value(123), + } + return types.ObjectValueMust(attrTypes, attrValues) + }, + expectedWorkspaceID: "", + expectError: true, + }, } for _, tt := range tests { @@ -267,6 +282,21 @@ func TestGetWorkspaceIDDataSource(t *testing.T) { expectedWorkspaceID: "", expectError: false, }, + { + name: "incompatible object structure", + setupProviderConfig: func() types.Object { + // Create an object with wrong attribute types to trigger conversion error + attrTypes := map[string]attr.Type{ + "workspace_id": types.Int64Type, + } + attrValues := map[string]attr.Value{ + "workspace_id": types.Int64Value(123), + } + return types.ObjectValueMust(attrTypes, attrValues) + }, + expectedWorkspaceID: "", + expectError: true, + }, } for _, tt := range tests { From 751fdb4f7ac30b0cc01d37bab428a87e7f34ba06 Mon Sep 17 00:00:00 2001 From: Tanmay Rustagi Date: Fri, 24 Oct 2025 02:58:52 +0530 Subject: [PATCH 8/8] more tests --- .../products/app/resource_app_acc_test.go | 79 +++++++++++++++++++ .../products/sharing/data_share_acc_test.go | 76 ++++++++++++++++++ 2 files changed, 155 insertions(+) create mode 100644 internal/providers/pluginfw/products/sharing/data_share_acc_test.go diff --git a/internal/providers/pluginfw/products/app/resource_app_acc_test.go b/internal/providers/pluginfw/products/app/resource_app_acc_test.go index cb4ae75805..3346a9a7a0 100644 --- a/internal/providers/pluginfw/products/app/resource_app_acc_test.go +++ b/internal/providers/pluginfw/products/app/resource_app_acc_test.go @@ -1,13 +1,17 @@ package app_test import ( + "context" "fmt" "regexp" + "strconv" "testing" + "github.com/databricks/databricks-sdk-go" "github.com/databricks/terraform-provider-databricks/internal/acceptance" "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) const baseResources = ` @@ -186,3 +190,78 @@ func TestAccAppResource_NoCompute(t *testing.T) { }, }) } + +func appTemplate(provider_config string) string { + return fmt.Sprintf(` + resource "databricks_secret_scope" "this" { + name = "tf-{var.STICKY_RANDOM}" + } + resource "databricks_secret" "this" { + scope = databricks_secret_scope.this.name + key = "tf-{var.STICKY_RANDOM}" + string_value = "secret" + } + resource "databricks_app" "this" { + %s + no_compute = true + name = "tf-{var.STICKY_RANDOM}" + description = "no_compute app" + resources = [{ + name = "secret" + description = "secret for app" + secret = { + scope = databricks_secret_scope.this.name + key = databricks_secret.this.key + permission = "MANAGE" + } + }] + } + `, provider_config) +} + +func TestAccApp_ProviderConfig_Invalid(t *testing.T) { + acceptance.UnityWorkspaceLevel(t, acceptance.Step{ + Template: appTemplate(` + provider_config = { + workspace_id = "invalid" + } + `), + ExpectError: regexp.MustCompile( + `Attribute provider_config\.workspace_id\s+workspace_id must be a valid integer`, + ), + PlanOnly: true, + }) +} + +func TestAccApp_ProviderConfig_Mismatched(t *testing.T) { + acceptance.UnityWorkspaceLevel(t, acceptance.Step{ + Template: appTemplate(` + provider_config = { + workspace_id = "123" + } + `), + ExpectError: regexp.MustCompile( + `(?s)failed to get workspace client.*workspace_id mismatch` + + `.*please check the workspace_id provided in ` + + `provider_config`, + ), + }) +} + +func TestAccApp_ProviderConfig_Apply(t *testing.T) { + acceptance.LoadUcwsEnv(t) + ctx := context.Background() + w := databricks.Must(databricks.NewWorkspaceClient()) + workspaceID, err := w.CurrentWorkspaceID(ctx) + require.NoError(t, err) + workspaceIDStr := strconv.FormatInt(workspaceID, 10) + acceptance.UnityWorkspaceLevel(t, acceptance.Step{ + Template: appTemplate(``), + }, acceptance.Step{ + Template: appTemplate(fmt.Sprintf(` + provider_config = { + workspace_id = "%s" + } + `, workspaceIDStr)), + }) +} diff --git a/internal/providers/pluginfw/products/sharing/data_share_acc_test.go b/internal/providers/pluginfw/products/sharing/data_share_acc_test.go new file mode 100644 index 0000000000..881d1b2f39 --- /dev/null +++ b/internal/providers/pluginfw/products/sharing/data_share_acc_test.go @@ -0,0 +1,76 @@ +package sharing_test + +import ( + "context" + "fmt" + "regexp" + "strconv" + "testing" + + "github.com/databricks/databricks-sdk-go" + "github.com/databricks/terraform-provider-databricks/internal/acceptance" + "github.com/stretchr/testify/require" +) + +func dataSourceShareTemplate(provider_config string) string { + return fmt.Sprintf(` + resource "databricks_share" "myshare" { + name = "{var.STICKY_RANDOM}-share-config" + object { + name = databricks_schema.schema1.id + data_object_type = "SCHEMA" + } + } + data "databricks_share" "this" { + %s + name = databricks_share.myshare.name + } +`, provider_config) +} + +func TestAccShareData_ProviderConfig_Invalid(t *testing.T) { + acceptance.UnityWorkspaceLevel(t, acceptance.Step{ + Template: preTestTemplateSchema + dataSourceShareTemplate(` + provider_config = { + workspace_id = "invalid" + } + `), + ExpectError: regexp.MustCompile( + `Attribute provider_config\.workspace_id\s+workspace_id must be a valid integer`, + ), + PlanOnly: true, + }) +} + +func TestAccShareData_ProviderConfig_Mismatched(t *testing.T) { + acceptance.UnityWorkspaceLevel(t, acceptance.Step{ + Template: preTestTemplateSchema + dataSourceShareTemplate(` + provider_config = { + workspace_id = "123" + } + `), + ExpectError: regexp.MustCompile( + `(?s)failed to get workspace client.*workspace_id mismatch` + + `.*please check the workspace_id provided in ` + + `provider_config`, + ), + }) +} + +func TestAccShareData_ProviderConfig_Apply(t *testing.T) { + acceptance.LoadUcwsEnv(t) + ctx := context.Background() + w := databricks.Must(databricks.NewWorkspaceClient()) + workspaceID, err := w.CurrentWorkspaceID(ctx) + require.NoError(t, err) + workspaceIDStr := strconv.FormatInt(workspaceID, 10) + acceptance.UnityWorkspaceLevel(t, acceptance.Step{ + Template: preTestTemplateSchema + dataSourceShareTemplate(``), + }, acceptance.Step{ + Template: preTestTemplateSchema + dataSourceShareTemplate(fmt.Sprintf(` + provider_config = { + workspace_id = "%s" + } + `, workspaceIDStr)), + }) +}