Skip to content

Commit a0c6f07

Browse files
nkvuongmgyucht
andauthored
[Feature] add databricks_dashboards data source (#4521)
## Changes - Add `databricks_dashboards` data source. Resolve #4451 ## Tests <!-- How is this tested? Please see the checklist below and also describe any other relevant tests --> - [x] `make test` run locally - [x] relevant change in `docs/` folder - [x] covered with integration tests in `internal/acceptance` - [x] using Go SDK - [x] using TF Plugin Framework --------- Co-authored-by: Miles Yucht <[email protected]>
1 parent 095fcd5 commit a0c6f07

File tree

5 files changed

+200
-0
lines changed

5 files changed

+200
-0
lines changed

NEXT_CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
* Add support for cluster logs delivery to UC Volumes ([#4492](https://github.com/databricks/terraform-provider-databricks/pull/4492)).
88
* Expose more attributes for `databricks_connection` resource ([#4502](https://github.com/databricks/terraform-provider-databricks/pull/4502)).
9+
* Add `databricks_dashboards` resource ([#4521](https://github.com/databricks/terraform-provider-databricks/pull/4521))
910

1011
### Bug Fixes
1112

docs/data-sources/dashboards.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
---
2+
subcategory: "Workspace"
3+
---
4+
# databricks_dashboards Data Source
5+
6+
This data source allows you to retrieve information about Databricks [Dashboards](https://docs.databricks.com/en/dashboards/index.html).
7+
8+
## Example Usage
9+
10+
```hcl
11+
data "databricks_dashboards" "all" {
12+
}
13+
14+
resource "databricks_permissions" "dashboards_permissions" {
15+
depends = [ data.databricks_dashboards.all ]
16+
for_each = data.databricks_dashboards.all.dashboards[*].dashboard_id
17+
18+
dashboard_id = each.value
19+
20+
access_control {
21+
group_name = "Example Group"
22+
permission_level = "CAN_MANAGE"
23+
}
24+
}
25+
26+
```
27+
28+
## Argument Reference
29+
30+
The following arguments are supported:
31+
32+
* `dashboard_name_contains` - (Optional) A **case-insensitive** substring to filter Dashboards by their name.
33+
34+
## Attribute Reference
35+
36+
In addition to all arguments above, the following attributes are exported:
37+
38+
* `dashboards` - A list of dashboards matching the specified criteria. Each element contains the following attributes:
39+
* `dashboard_id` - The unique ID of the dashboard.
40+
* `display_name` - The display name of the dashboard.
41+
* `create_time` - The timestamp of when the dashboard was created.
42+
43+
If no matches are found, an empty list will be returned.

internal/providers/pluginfw/pluginfw_rollout_utils.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"github.com/databricks/terraform-provider-databricks/internal/providers/pluginfw/products/app"
1616
"github.com/databricks/terraform-provider-databricks/internal/providers/pluginfw/products/catalog"
1717
"github.com/databricks/terraform-provider-databricks/internal/providers/pluginfw/products/cluster"
18+
"github.com/databricks/terraform-provider-databricks/internal/providers/pluginfw/products/dashboards"
1819
"github.com/databricks/terraform-provider-databricks/internal/providers/pluginfw/products/library"
1920
"github.com/databricks/terraform-provider-databricks/internal/providers/pluginfw/products/notificationdestinations"
2021
"github.com/databricks/terraform-provider-databricks/internal/providers/pluginfw/products/qualitymonitor"
@@ -56,6 +57,7 @@ var pluginFwOnlyDataSources = append(
5657
app.DataSourceApp,
5758
app.DataSourceApps,
5859
catalog.DataSourceFunctions,
60+
dashboards.DataSourceDashboards,
5961
notificationdestinations.DataSourceNotificationDestinations,
6062
registered_model.DataSourceRegisteredModel,
6163
registered_model.DataSourceRegisteredModelVersions,
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
package dashboards
2+
3+
import (
4+
"context"
5+
"reflect"
6+
"strings"
7+
8+
"github.com/databricks/databricks-sdk-go/service/dashboards"
9+
"github.com/databricks/terraform-provider-databricks/common"
10+
pluginfwcommon "github.com/databricks/terraform-provider-databricks/internal/providers/pluginfw/common"
11+
pluginfwcontext "github.com/databricks/terraform-provider-databricks/internal/providers/pluginfw/context"
12+
"github.com/databricks/terraform-provider-databricks/internal/providers/pluginfw/converters"
13+
"github.com/databricks/terraform-provider-databricks/internal/providers/pluginfw/tfschema"
14+
"github.com/databricks/terraform-provider-databricks/internal/service/dashboards_tf"
15+
"github.com/hashicorp/terraform-plugin-framework/attr"
16+
"github.com/hashicorp/terraform-plugin-framework/datasource"
17+
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
18+
"github.com/hashicorp/terraform-plugin-framework/diag"
19+
"github.com/hashicorp/terraform-plugin-framework/types"
20+
)
21+
22+
const dataSourceName = "dashboards"
23+
24+
func DataSourceDashboards() datasource.DataSource {
25+
return &DashboardsDataSource{}
26+
}
27+
28+
var _ datasource.DataSourceWithConfigure = &DashboardsDataSource{}
29+
30+
type DashboardsDataSource struct {
31+
Client *common.DatabricksClient
32+
}
33+
34+
type DashboardsInfo struct {
35+
DashboardNameContains types.String `tfsdk:"dashboard_name_contains"`
36+
Dashboards types.List `tfsdk:"dashboards"`
37+
}
38+
39+
func (DashboardsInfo) ApplySchemaCustomizations(attrs map[string]tfschema.AttributeBuilder) map[string]tfschema.AttributeBuilder {
40+
attrs["dashboard_name_contains"] = attrs["dashboard_name_contains"].SetOptional()
41+
attrs["dashboards"] = attrs["dashboards"].SetComputed()
42+
43+
return attrs
44+
}
45+
46+
func (DashboardsInfo) GetComplexFieldTypes(context.Context) map[string]reflect.Type {
47+
return map[string]reflect.Type{
48+
"dashboards": reflect.TypeOf(dashboards_tf.Dashboard{}),
49+
}
50+
}
51+
52+
func (d *DashboardsDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
53+
resp.TypeName = pluginfwcommon.GetDatabricksProductionName(dataSourceName)
54+
}
55+
56+
func (d *DashboardsDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
57+
attrs, blocks := tfschema.DataSourceStructToSchemaMap(ctx, DashboardsInfo{}, nil)
58+
resp.Schema = schema.Schema{
59+
Attributes: attrs,
60+
Blocks: blocks,
61+
}
62+
}
63+
64+
func (d *DashboardsDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
65+
if d.Client == nil {
66+
d.Client = pluginfwcommon.ConfigureDataSource(req, resp)
67+
}
68+
}
69+
70+
func AppendDiagAndCheckErrors(resp *datasource.ReadResponse, diags diag.Diagnostics) bool {
71+
resp.Diagnostics.Append(diags...)
72+
return resp.Diagnostics.HasError()
73+
}
74+
75+
func (d *DashboardsDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
76+
ctx = pluginfwcontext.SetUserAgentInDataSourceContext(ctx, dataSourceName)
77+
w, diags := d.Client.GetWorkspaceClient()
78+
if AppendDiagAndCheckErrors(resp, diags) {
79+
return
80+
}
81+
82+
var dashboardInfo DashboardsInfo
83+
if AppendDiagAndCheckErrors(resp, req.Config.Get(ctx, &dashboardInfo)) {
84+
return
85+
}
86+
87+
dashboardName := strings.ToLower(dashboardInfo.DashboardNameContains.ValueString())
88+
89+
dashboardsGoSdk, err := w.Lakeview.ListAll(ctx, dashboards.ListDashboardsRequest{})
90+
if err != nil {
91+
resp.Diagnostics.AddError("Failed to fetch Dashboards", err.Error())
92+
return
93+
}
94+
95+
var dashboardsTfSdk []attr.Value
96+
for _, dashboard := range dashboardsGoSdk {
97+
if dashboardName != "" && !strings.Contains(strings.ToLower(dashboard.DisplayName), dashboardName) {
98+
continue
99+
}
100+
101+
var dashboardResponse dashboards_tf.Dashboard
102+
if AppendDiagAndCheckErrors(resp, converters.GoSdkToTfSdkStruct(ctx, dashboard, &dashboardResponse)) {
103+
return
104+
}
105+
dashboardsTfSdk = append(dashboardsTfSdk, dashboardResponse.ToObjectValue(ctx))
106+
}
107+
108+
dashboardInfo.Dashboards = types.ListValueMust(dashboards_tf.Dashboard{}.Type(ctx), dashboardsTfSdk)
109+
resp.Diagnostics.Append(resp.State.Set(ctx, dashboardInfo)...)
110+
111+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package dashboards_test
2+
3+
import (
4+
"strconv"
5+
"testing"
6+
7+
"github.com/databricks/terraform-provider-databricks/internal/acceptance"
8+
"github.com/hashicorp/terraform-plugin-testing/terraform"
9+
"github.com/stretchr/testify/require"
10+
)
11+
12+
func CheckDataSourceDashboardsPopulated(t *testing.T) func(s *terraform.State) error {
13+
return func(s *terraform.State) error {
14+
ds, ok := s.Modules[0].Resources["data.databricks_dashboards.this"]
15+
require.True(t, ok, "data.databricks_dashboards.this has to be there")
16+
17+
dashboardsCount := ds.Primary.Attributes["dashboards.#"]
18+
dashboardsCountInt, err := strconv.Atoi(dashboardsCount)
19+
require.NoError(t, err, "dashboards count is not a number")
20+
require.NotEqual(t, 0, dashboardsCountInt, "dashboard list is empty")
21+
22+
return nil
23+
}
24+
}
25+
26+
func TestAccDashboardsDataSource(t *testing.T) {
27+
acceptance.WorkspaceLevel(t, acceptance.Step{
28+
Template: `
29+
resource "databricks_dashboard" "dashboard" {
30+
display_name = "New Dashboard"
31+
warehouse_id = "{env.TEST_DEFAULT_WAREHOUSE_ID}"
32+
serialized_dashboard = "{\"pages\":[{\"name\":\"new_name\",\"displayName\":\"New Page\"}]}"
33+
embed_credentials = false // Optional
34+
parent_path = "/Shared/provider-test"
35+
}
36+
37+
data "databricks_dashboards" "this" {
38+
depends_on = [databricks_dashboard.dashboard]
39+
}
40+
`,
41+
Check: CheckDataSourceDashboardsPopulated(t),
42+
})
43+
}

0 commit comments

Comments
 (0)