Skip to content

Commit

Permalink
[Feature] Automatically create parent_path folder if it doesn't exi…
Browse files Browse the repository at this point in the history
…st (#3778)

## Changes
<!-- Summary of your changes that are easy to understand -->

This makes behavior consistent with other workspace objects - notebooks,
workspace files, etc.

I have the skeleton of the test for it, but it doesn't work because I
can't mock the same API call two times with different return results

## Tests
<!-- 
How is this tested? Please see the checklist below and also describe any
other relevant tests
-->

- [x] `make test` run locally
- [x] relevant change in `docs/` folder
- [ ] covered with integration tests in `internal/acceptance`
- [ ] relevant acceptance tests are passing
- [x] using Go SDK
  • Loading branch information
alexott authored Aug 22, 2024
1 parent 0e9f500 commit aff97af
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 1 deletion.
15 changes: 15 additions & 0 deletions dashboards/resource_dashboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package dashboards

import (
"context"
"log"
"strings"

"github.com/databricks/databricks-sdk-go/service/dashboards"
"github.com/databricks/terraform-provider-databricks/common"
Expand Down Expand Up @@ -75,6 +77,14 @@ func ResourceDashboard() common.Resource {
d.Set("md5", md5Hash)
newDashboardRequest.SerializedDashboard = content
createdDashboard, err := w.Lakeview.Create(ctx, newDashboardRequest)
if err != nil && isParentDoesntExistError(err) {
log.Printf("[DEBUG] Parent folder '%s' doesn't exist, creating...", newDashboardRequest.ParentPath)
err = w.Workspace.MkdirsByPath(ctx, newDashboardRequest.ParentPath)
if err != nil {
return err
}
createdDashboard, err = w.Lakeview.Create(ctx, newDashboardRequest)
}
if err != nil {
return err
}
Expand Down Expand Up @@ -168,3 +178,8 @@ func ResourceDashboard() common.Resource {
},
}
}

func isParentDoesntExistError(err error) bool {
errStr := err.Error()
return strings.HasPrefix(errStr, "Path (") && strings.HasSuffix(errStr, ") doesn't exist.")
}
59 changes: 59 additions & 0 deletions dashboards/resource_dashboard_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package dashboards

import (
"fmt"
"testing"

"github.com/databricks/databricks-sdk-go/experimental/mocks"
Expand Down Expand Up @@ -61,6 +62,64 @@ func TestDashboardCreate(t *testing.T) {
})
}

func TestDashboardCreate_NoParent(t *testing.T) {
qa.ResourceFixture{
MockWorkspaceClientFunc: func(w *mocks.MockWorkspaceClient) {
lv := w.GetMockLakeviewAPI().EXPECT()
lv.Create(mock.Anything, dashboards.CreateDashboardRequest{
DisplayName: "Dashboard name",
WarehouseId: "abc",
ParentPath: "/path",
SerializedDashboard: "serialized_json",
}).Return(nil, fmt.Errorf("Path (/path) doesn't exist.")).Once()
w.GetMockWorkspaceAPI().EXPECT().MkdirsByPath(mock.Anything, "/path").Return(nil)
lv.Create(mock.Anything, dashboards.CreateDashboardRequest{
DisplayName: "Dashboard name",
WarehouseId: "abc",
ParentPath: "/path",
SerializedDashboard: "serialized_json",
}).Return(&dashboards.Dashboard{
DashboardId: "xyz",
DisplayName: "Dashboard name",
SerializedDashboard: "serialized_json_2",
WarehouseId: "abc",
UpdateTime: "2125678",
}, nil)
lv.Publish(mock.Anything, dashboards.PublishRequest{
EmbedCredentials: true,
WarehouseId: "abc",
DashboardId: "xyz",
ForceSendFields: []string{"EmbedCredentials"},
}).Return(&dashboards.PublishedDashboard{
EmbedCredentials: true,
WarehouseId: "abc",
DisplayName: "Dashboard name",
RevisionCreateTime: "823828",
}, nil)
lv.Get(mock.Anything, dashboards.GetDashboardRequest{
DashboardId: "xyz",
}).Return(&dashboards.Dashboard{
DashboardId: "xyz",
DisplayName: "Dashboard name",
SerializedDashboard: "serialized_json_2",
WarehouseId: "abc",
UpdateTime: "2125678",
}, nil)
},
Resource: ResourceDashboard(),
Create: true,
HCL: `
display_name = "Dashboard name"
warehouse_id = "abc"
parent_path = "/path"
serialized_dashboard = "serialized_json"
`,
}.ApplyAndExpectData(t, map[string]any{
"id": "xyz",
"display_name": "Dashboard name",
})
}

func TestDashboardRead(t *testing.T) {
qa.ResourceFixture{
MockWorkspaceClientFunc: func(w *mocks.MockWorkspaceClient) {
Expand Down
2 changes: 1 addition & 1 deletion docs/resources/dashboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ The following arguments are supported:
* `serialized_dashboard` - (Optional) The contents of the dashboard in serialized string form. Conflicts with `file_path`.
* `file_path` - (Optional) The path to the dashboard JSON file. Conflicts with `serialized_dashboard`.
* `embed_credentials` - (Optional) Whether to embed credentials in the dashboard. Default is `true`.
* `parent_path` - (Required) The workspace path of the folder containing the dashboard. Includes leading slash and no trailing slash.
* `parent_path` - (Required) The workspace path of the folder containing the dashboard. Includes leading slash and no trailing slash. If folder doesn't exist, it will be created.

## Attribute Reference

Expand Down

0 comments on commit aff97af

Please sign in to comment.